mirror of
https://github.com/kanjitalk755/macemu.git
synced 2024-09-07 16:54:28 +00:00
cdenable interface
This commit is contained in:
parent
67399201bb
commit
c26be68be4
182
BasiliskII/src/Windows/cdenable/cache.cpp
Executable file
182
BasiliskII/src/Windows/cdenable/cache.cpp
Executable file
@ -0,0 +1,182 @@
|
||||
/*
|
||||
* cache.cpp - simple floppy/cd cache for Win32
|
||||
*
|
||||
* Basilisk II (C) 1997-1999 Christian Bauer
|
||||
*
|
||||
* Windows platform specific code copyright (C) Lauri Pesonen
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
/*
|
||||
Note that this is particularly silly cache code
|
||||
and doesn't even use hash buckets. It is sufficient
|
||||
for floppies and maybe emulated cd's but that's it.
|
||||
*/
|
||||
|
||||
#include "sysdeps.h"
|
||||
#include "windows.h"
|
||||
#include "cache.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifdef _DEBUG
|
||||
#define new DEBUG_NEW
|
||||
#undef THIS_FILE
|
||||
static char THIS_FILE[] = __FILE__;
|
||||
#endif
|
||||
|
||||
void cache_clear( cachetype *cptr )
|
||||
{
|
||||
if(cptr->inited) {
|
||||
cptr->res_count = 0;
|
||||
memset( cptr->LRU, 0, NBLOCKS * sizeof(int) );
|
||||
}
|
||||
}
|
||||
|
||||
static int init( cachetype *cptr, int sector_size )
|
||||
{
|
||||
cache_clear( cptr );
|
||||
cptr->sector_size = sector_size;
|
||||
cptr->blocks = (char *)VirtualAlloc(
|
||||
NULL, NBLOCKS*sector_size,
|
||||
MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE );
|
||||
cptr->block = (int *)VirtualAlloc(
|
||||
NULL, NBLOCKS*sizeof(int),
|
||||
MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE );
|
||||
cptr->LRU = (DWORD *)VirtualAlloc(
|
||||
NULL, NBLOCKS*sizeof(DWORD),
|
||||
MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE );
|
||||
return(cptr->blocks != NULL);
|
||||
}
|
||||
|
||||
static void final( cachetype *cptr )
|
||||
{
|
||||
if(cptr->blocks) {
|
||||
VirtualFree( cptr->blocks, 0, MEM_RELEASE );
|
||||
cptr->blocks = 0;
|
||||
}
|
||||
if(cptr->block) {
|
||||
VirtualFree( cptr->block, 0, MEM_RELEASE );
|
||||
cptr->block = 0;
|
||||
}
|
||||
if(cptr->LRU) {
|
||||
VirtualFree( cptr->LRU, 0, MEM_RELEASE );
|
||||
cptr->LRU = 0;
|
||||
}
|
||||
cptr->inited = 0;
|
||||
}
|
||||
|
||||
void cache_init( cachetype *cptr )
|
||||
{
|
||||
cptr->inited = 0;
|
||||
}
|
||||
|
||||
void cache_final( cachetype *cptr )
|
||||
{
|
||||
if(cptr->inited) {
|
||||
final( cptr );
|
||||
cptr->inited = 0;
|
||||
}
|
||||
}
|
||||
|
||||
static int in_cache( cachetype *cptr, int block )
|
||||
{
|
||||
int i;
|
||||
for(i=cptr->res_count-1; i>=0; i--) {
|
||||
if(cptr->block[i] == block) return(i);
|
||||
}
|
||||
return(-1);
|
||||
}
|
||||
|
||||
static int get_LRU( cachetype *cptr )
|
||||
{
|
||||
int i, result = 0;
|
||||
DWORD mtime = cptr->LRU[0];
|
||||
|
||||
for(i=1; i<NBLOCKS; i++) {
|
||||
if(cptr->LRU[i] < mtime) {
|
||||
mtime = cptr->LRU[i];
|
||||
result = i;
|
||||
}
|
||||
}
|
||||
return(result);
|
||||
}
|
||||
|
||||
void cache_put( cachetype *cptr, int block, char *buf, int ss )
|
||||
{
|
||||
int inx;
|
||||
|
||||
if(!cptr->inited) {
|
||||
if(!init(cptr,ss)) return;
|
||||
cptr->inited = 1;
|
||||
}
|
||||
inx = in_cache( cptr, block );
|
||||
if(inx < 0) {
|
||||
if(cptr->res_count == NBLOCKS) {
|
||||
inx = get_LRU( cptr );
|
||||
} else {
|
||||
inx = cptr->res_count++;
|
||||
}
|
||||
cptr->block[inx] = block;
|
||||
}
|
||||
cptr->LRU[inx] = GetTickCount();
|
||||
memcpy( cptr->blocks + inx * ss, buf, ss );
|
||||
}
|
||||
|
||||
int cache_get( cachetype *cptr, int block, char *buf )
|
||||
{
|
||||
int inx;
|
||||
|
||||
if(!cptr->inited) return(0);
|
||||
|
||||
inx = in_cache( cptr, block );
|
||||
if(inx >= 0) {
|
||||
memcpy( buf, cptr->blocks + inx * cptr->sector_size, cptr->sector_size );
|
||||
return(1);
|
||||
} else {
|
||||
return(0);
|
||||
}
|
||||
}
|
||||
|
||||
void cache_remove( cachetype *cptr, int block, int ss )
|
||||
{
|
||||
int inx, from;
|
||||
|
||||
if(!cptr->inited) {
|
||||
if(!init(cptr,ss)) return;
|
||||
cptr->inited = 1;
|
||||
}
|
||||
inx = in_cache( cptr, block );
|
||||
if(inx >= 0) {
|
||||
if(cptr->res_count > 1) {
|
||||
from = cptr->res_count-1;
|
||||
cptr->block[inx] = cptr->block[from];
|
||||
cptr->LRU[inx] = cptr->LRU[from];
|
||||
memcpy(
|
||||
cptr->blocks + inx * cptr->sector_size,
|
||||
cptr->blocks + from * cptr->sector_size,
|
||||
cptr->sector_size
|
||||
);
|
||||
}
|
||||
cptr->res_count--;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
50
BasiliskII/src/Windows/cdenable/cache.h
Executable file
50
BasiliskII/src/Windows/cdenable/cache.h
Executable file
@ -0,0 +1,50 @@
|
||||
/*
|
||||
* cache.cpp - simple floppy/cd cache for Win32
|
||||
*
|
||||
* Basilisk II (C) 1997-1999 Christian Bauer
|
||||
*
|
||||
* Windows platform specific code copyright (C) Lauri Pesonen
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifndef _CACHE_H_
|
||||
#define _CACHE_H_
|
||||
#define NBLOCKS 1000
|
||||
|
||||
typedef struct {
|
||||
int inited;
|
||||
int res_count;
|
||||
int sector_size;
|
||||
char *blocks;
|
||||
int *block;
|
||||
DWORD *LRU;
|
||||
} cachetype;
|
||||
|
||||
void cache_init( cachetype *cptr );
|
||||
void cache_clear( cachetype *cptr );
|
||||
void cache_final( cachetype *cptr );
|
||||
int cache_get( cachetype *cptr, int block, char *buf );
|
||||
void cache_put( cachetype *cptr, int block, char *buf, int ss );
|
||||
void cache_remove( cachetype *cptr, int block, int ss );
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
60
BasiliskII/src/Windows/cdenable/cdenable.h
Executable file
60
BasiliskII/src/Windows/cdenable/cdenable.h
Executable file
@ -0,0 +1,60 @@
|
||||
/*
|
||||
* cdenable.h - cdenable.vxd definitions
|
||||
*
|
||||
* Basilisk II (C) 1997-1999 Christian Bauer
|
||||
*
|
||||
* Windows platform specific code copyright (C) Lauri Pesonen
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
// max read requests, if larger -> STATUS_INVALID_PARAMETER
|
||||
#define CDENABLE_MAX_TRANSFER_SIZE (0x10000)
|
||||
|
||||
|
||||
// A structure representing the instance information associated with
|
||||
// a particular device
|
||||
typedef struct _DEVICE_EXTENSION
|
||||
{
|
||||
// not needed.
|
||||
ULONG StateVariable;
|
||||
} DEVICE_EXTENSION, *PDEVICE_EXTENSION;
|
||||
|
||||
|
||||
// Define the various device type values. Note that values used by Microsoft
|
||||
// Corporation are in the range 0-32767, and 32768-65535 are reserved for use
|
||||
// by customers.
|
||||
#define FILE_DEVICE_CDENABLE 0x00008301
|
||||
|
||||
|
||||
// Target NT version, internal version
|
||||
#define CDENABLE_CURRENT_VERSION 0x04000100
|
||||
|
||||
|
||||
// Macro definition for defining IOCTL and FSCTL function control codes. Note
|
||||
// that function codes 0-2047 are reserved for Microsoft Corporation, and
|
||||
// 2048-4095 are reserved for customers.
|
||||
#define CDENABLE_IOCTL_READ 0x830
|
||||
#define CDENABLE_IOCTL_GET_VERSION 0x831
|
||||
|
||||
|
||||
#define IOCTL_CDENABLE_READ CTL_CODE(FILE_DEVICE_CDENABLE, \
|
||||
CDENABLE_IOCTL_READ, \
|
||||
METHOD_BUFFERED, \
|
||||
FILE_ANY_ACCESS)
|
||||
#define IOCTL_CDENABLE_GET_VERSION CTL_CODE(FILE_DEVICE_CDENABLE, \
|
||||
CDENABLE_IOCTL_GET_VERSION, \
|
||||
METHOD_BUFFERED, \
|
||||
FILE_ANY_ACCESS)
|
190
BasiliskII/src/Windows/cdenable/eject_nt.cpp
Executable file
190
BasiliskII/src/Windows/cdenable/eject_nt.cpp
Executable file
@ -0,0 +1,190 @@
|
||||
/*
|
||||
* eject_nt.cpp - cd eject routines for WinNT (derived from MS samples)
|
||||
*
|
||||
* Basilisk II (C) 1997-1999 Christian Bauer
|
||||
*
|
||||
* Windows platform specific code copyright (C) Lauri Pesonen
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include "sysdeps.h"
|
||||
|
||||
#include "windows.h"
|
||||
#include <winioctl.h>
|
||||
|
||||
// Prototypes
|
||||
|
||||
extern "C" {
|
||||
|
||||
#include "eject_nt.h"
|
||||
|
||||
LPTSTR szVolumeFormat = TEXT("\\\\.\\%c:");
|
||||
LPTSTR szRootFormat = TEXT("%c:\\");
|
||||
LPTSTR szErrorFormat = TEXT("Error %d: %s\n");
|
||||
|
||||
void ReportError(LPTSTR szMsg)
|
||||
{
|
||||
// _tprintf(szErrorFormat, GetLastError(), szMsg);
|
||||
}
|
||||
|
||||
HANDLE OpenVolume(TCHAR cDriveLetter)
|
||||
{
|
||||
HANDLE hVolume;
|
||||
UINT uDriveType;
|
||||
TCHAR szVolumeName[8];
|
||||
TCHAR szRootName[5];
|
||||
DWORD dwAccessFlags;
|
||||
|
||||
wsprintf(szRootName, szRootFormat, cDriveLetter);
|
||||
|
||||
uDriveType = GetDriveType(szRootName);
|
||||
switch(uDriveType) {
|
||||
case DRIVE_REMOVABLE:
|
||||
dwAccessFlags = GENERIC_READ | GENERIC_WRITE;
|
||||
break;
|
||||
case DRIVE_CDROM:
|
||||
dwAccessFlags = GENERIC_READ;
|
||||
break;
|
||||
default:
|
||||
// _tprintf(TEXT("Cannot eject. Drive type is incorrect.\n"));
|
||||
return INVALID_HANDLE_VALUE;
|
||||
}
|
||||
|
||||
wsprintf(szVolumeName, szVolumeFormat, cDriveLetter);
|
||||
|
||||
hVolume = CreateFile( szVolumeName,
|
||||
dwAccessFlags,
|
||||
FILE_SHARE_READ | FILE_SHARE_WRITE,
|
||||
NULL,
|
||||
OPEN_EXISTING,
|
||||
0,
|
||||
NULL );
|
||||
if (hVolume == INVALID_HANDLE_VALUE)
|
||||
ReportError(TEXT("CreateFile"));
|
||||
|
||||
return hVolume;
|
||||
}
|
||||
|
||||
BOOL CloseVolume(HANDLE hVolume)
|
||||
{
|
||||
return CloseHandle(hVolume);
|
||||
}
|
||||
|
||||
#define LOCK_TIMEOUT 1000 // 1 second
|
||||
#define LOCK_RETRIES 20
|
||||
|
||||
BOOL LockVolume(HANDLE hVolume)
|
||||
{
|
||||
DWORD dwBytesReturned;
|
||||
DWORD dwSleepAmount;
|
||||
int nTryCount;
|
||||
|
||||
dwSleepAmount = LOCK_TIMEOUT / LOCK_RETRIES;
|
||||
|
||||
// Do this in a loop until a timeout period has expired
|
||||
for (nTryCount = 0; nTryCount < LOCK_RETRIES; nTryCount++) {
|
||||
if (DeviceIoControl(hVolume,
|
||||
FSCTL_LOCK_VOLUME,
|
||||
NULL, 0,
|
||||
NULL, 0,
|
||||
&dwBytesReturned,
|
||||
NULL))
|
||||
return TRUE;
|
||||
|
||||
Sleep(dwSleepAmount);
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
BOOL DismountVolume(HANDLE hVolume)
|
||||
{
|
||||
DWORD dwBytesReturned;
|
||||
|
||||
return DeviceIoControl( hVolume,
|
||||
FSCTL_DISMOUNT_VOLUME,
|
||||
NULL, 0,
|
||||
NULL, 0,
|
||||
&dwBytesReturned,
|
||||
NULL);
|
||||
}
|
||||
|
||||
BOOL PreventRemovalOfVolume(HANDLE hVolume, BOOL fPreventRemoval)
|
||||
{
|
||||
DWORD dwBytesReturned;
|
||||
PREVENT_MEDIA_REMOVAL PMRBuffer;
|
||||
|
||||
PMRBuffer.PreventMediaRemoval = fPreventRemoval;
|
||||
|
||||
return DeviceIoControl( hVolume,
|
||||
IOCTL_STORAGE_MEDIA_REMOVAL,
|
||||
&PMRBuffer, sizeof(PREVENT_MEDIA_REMOVAL),
|
||||
NULL, 0,
|
||||
&dwBytesReturned,
|
||||
NULL);
|
||||
}
|
||||
|
||||
BOOL AutoEjectVolume( HANDLE hVolume, BOOL reload )
|
||||
{
|
||||
DWORD dwBytesReturned;
|
||||
|
||||
return DeviceIoControl( hVolume,
|
||||
reload ? IOCTL_STORAGE_LOAD_MEDIA : IOCTL_STORAGE_EJECT_MEDIA,
|
||||
NULL, 0,
|
||||
NULL, 0,
|
||||
&dwBytesReturned,
|
||||
NULL);
|
||||
}
|
||||
|
||||
BOOL EjectVolume( TCHAR cDriveLetter, BOOL reload )
|
||||
{
|
||||
HANDLE hVolume;
|
||||
|
||||
BOOL fRemoveSafely = FALSE;
|
||||
BOOL fAutoEject = FALSE;
|
||||
|
||||
// Open the volume.
|
||||
hVolume = OpenVolume(cDriveLetter);
|
||||
if (hVolume == INVALID_HANDLE_VALUE)
|
||||
return FALSE;
|
||||
|
||||
// Lock and dismount the volume.
|
||||
if (LockVolume(hVolume) && DismountVolume(hVolume)) {
|
||||
fRemoveSafely = TRUE;
|
||||
|
||||
// Set prevent removal to false and eject the volume.
|
||||
if (PreventRemovalOfVolume(hVolume, FALSE) &&
|
||||
AutoEjectVolume(hVolume,reload))
|
||||
fAutoEject = TRUE;
|
||||
}
|
||||
|
||||
// Close the volume so other processes can use the drive.
|
||||
if (!CloseVolume(hVolume))
|
||||
return FALSE;
|
||||
|
||||
/*
|
||||
if (fAutoEject)
|
||||
printf("Media in Drive %c has been ejected safely.\n", cDriveLetter);
|
||||
else {
|
||||
if (fRemoveSafely)
|
||||
printf("Media in Drive %c can be safely removed.\n", cDriveLetter);
|
||||
}
|
||||
*/
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
} // extern "C"
|
44
BasiliskII/src/Windows/cdenable/eject_nt.h
Executable file
44
BasiliskII/src/Windows/cdenable/eject_nt.h
Executable file
@ -0,0 +1,44 @@
|
||||
/*
|
||||
* eject_nt.cpp - cd eject routines for WinNT (derived from MS samples)
|
||||
*
|
||||
* Basilisk II (C) 1997-1999 Christian Bauer
|
||||
*
|
||||
* Windows platform specific code copyright (C) Lauri Pesonen
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifndef _EJECT_NT_H_
|
||||
#define _EJECT_NT_H_
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
BOOL EjectVolume(TCHAR cDriveLetter,BOOL reload);
|
||||
|
||||
HANDLE OpenVolume(TCHAR cDriveLetter);
|
||||
BOOL LockVolume(HANDLE hVolume);
|
||||
BOOL DismountVolume(HANDLE hVolume);
|
||||
BOOL PreventRemovalOfVolume(HANDLE hVolume, BOOL fPrevent);
|
||||
BOOL AutoEjectVolume(HANDLE hVolume,BOOL reload);
|
||||
BOOL CloseVolume(HANDLE hVolume);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
||||
#endif //_EJECT_NT_H_
|
345
BasiliskII/src/Windows/cdenable/ntcd.cpp
Executable file
345
BasiliskII/src/Windows/cdenable/ntcd.cpp
Executable file
@ -0,0 +1,345 @@
|
||||
/*
|
||||
* ntcd.cpp - Interface to cdenable.sys driver
|
||||
*
|
||||
* Basilisk II (C) 1997-1999 Christian Bauer
|
||||
*
|
||||
* Windows platform specific code copyright (C) Lauri Pesonen
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include "sysdeps.h"
|
||||
#include <windows.h>
|
||||
|
||||
extern "C" {
|
||||
|
||||
#include <winioctl.h>
|
||||
#include <winsvc.h>
|
||||
#include "ntcd.h"
|
||||
#include "cdenable.h"
|
||||
|
||||
static char *sDriverShort = "cdenable";
|
||||
static char *sDriverLong = "System32\\Drivers\\cdenable.sys";
|
||||
static char *sCompleteName = "\\\\.\\cdenable";
|
||||
|
||||
#ifdef _DEBUG
|
||||
#define new DEBUG_NEW
|
||||
#undef THIS_FILE
|
||||
static char THIS_FILE[] = __FILE__;
|
||||
#endif
|
||||
|
||||
// Start type must be SERVICE_AUTO_START or lower, in order
|
||||
// it to start automatically and allow the mechanism work
|
||||
// for users with no admin rights.
|
||||
static BOOL InstallDriver(
|
||||
IN SC_HANDLE SchSCManager,
|
||||
IN LPCTSTR DriverName,
|
||||
IN LPCTSTR ServiceExe
|
||||
)
|
||||
{
|
||||
SC_HANDLE schService;
|
||||
DWORD err;
|
||||
|
||||
schService = CreateService (
|
||||
SchSCManager, // SCManager database
|
||||
DriverName, // name of service
|
||||
DriverName, // name to display
|
||||
SERVICE_ALL_ACCESS, // desired access
|
||||
SERVICE_KERNEL_DRIVER, // service type
|
||||
SERVICE_AUTO_START, // SERVICE_DEMAND_START, // start type
|
||||
SERVICE_ERROR_NORMAL, // error control type
|
||||
ServiceExe, // service's binary
|
||||
NULL, // no load ordering group
|
||||
NULL, // no tag identifier
|
||||
NULL, // no dependencies
|
||||
NULL, // LocalSystem account
|
||||
NULL // no password
|
||||
);
|
||||
|
||||
if (schService == NULL) {
|
||||
err = GetLastError();
|
||||
if (err == ERROR_SERVICE_EXISTS) {
|
||||
return TRUE;
|
||||
} else {
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
CloseServiceHandle (schService);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static BOOL RemoveDriver(
|
||||
IN SC_HANDLE SchSCManager,
|
||||
IN LPCTSTR DriverName
|
||||
)
|
||||
{
|
||||
SC_HANDLE schService;
|
||||
BOOL ret;
|
||||
|
||||
schService = OpenService (SchSCManager,
|
||||
DriverName,
|
||||
SERVICE_ALL_ACCESS
|
||||
);
|
||||
if (schService == NULL) return FALSE;
|
||||
ret = DeleteService (schService);
|
||||
CloseServiceHandle (schService);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static BOOL StartDriver(
|
||||
IN SC_HANDLE SchSCManager,
|
||||
IN LPCTSTR DriverName
|
||||
) {
|
||||
SC_HANDLE schService;
|
||||
BOOL ret;
|
||||
DWORD err;
|
||||
|
||||
schService = OpenService (SchSCManager,
|
||||
DriverName,
|
||||
SERVICE_ALL_ACCESS
|
||||
);
|
||||
if (schService == NULL) return FALSE;
|
||||
ret = StartService (schService, // service identifier
|
||||
0, // number of arguments
|
||||
NULL // pointer to arguments
|
||||
);
|
||||
if(ret == 0) {
|
||||
err = GetLastError();
|
||||
if (err == ERROR_SERVICE_ALREADY_RUNNING) {
|
||||
ret = TRUE;
|
||||
} else {
|
||||
ret = FALSE;
|
||||
}
|
||||
}
|
||||
CloseServiceHandle (schService);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static BOOL StopDriver(
|
||||
IN SC_HANDLE SchSCManager,
|
||||
IN LPCTSTR DriverName
|
||||
)
|
||||
{
|
||||
SC_HANDLE schService;
|
||||
BOOL ret;
|
||||
SERVICE_STATUS serviceStatus;
|
||||
|
||||
schService = OpenService (SchSCManager,
|
||||
DriverName,
|
||||
SERVICE_ALL_ACCESS
|
||||
);
|
||||
if (schService == NULL) return FALSE;
|
||||
ret = ControlService (schService,
|
||||
SERVICE_CONTROL_STOP,
|
||||
&serviceStatus
|
||||
);
|
||||
CloseServiceHandle (schService);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static BOOL __cdecl start_driver( void )
|
||||
{
|
||||
SC_HANDLE schSCManager;
|
||||
BOOL ret = FALSE;
|
||||
|
||||
schSCManager = OpenSCManager( NULL, NULL, SC_MANAGER_ALL_ACCESS );
|
||||
if(!schSCManager) return(FALSE);
|
||||
if(!InstallDriver( schSCManager, sDriverShort, sDriverLong )) {
|
||||
CloseServiceHandle( schSCManager );
|
||||
return(FALSE);
|
||||
}
|
||||
ret = StartDriver( schSCManager, sDriverShort );
|
||||
if(!ret) {
|
||||
(void)RemoveDriver( schSCManager, sDriverShort );
|
||||
}
|
||||
CloseServiceHandle( schSCManager );
|
||||
return( ret );
|
||||
}
|
||||
|
||||
static BOOL __cdecl stop_driver( void )
|
||||
{
|
||||
SC_HANDLE schSCManager;
|
||||
BOOL ret = FALSE;
|
||||
|
||||
schSCManager = OpenSCManager( NULL, NULL, SC_MANAGER_ALL_ACCESS );
|
||||
if(!schSCManager) return(FALSE);
|
||||
if(StopDriver( schSCManager, sDriverShort )) ret = TRUE;
|
||||
CloseServiceHandle( schSCManager );
|
||||
return( ret );
|
||||
}
|
||||
|
||||
static BOOL __cdecl remove_driver( void )
|
||||
{
|
||||
SC_HANDLE schSCManager;
|
||||
BOOL ret = FALSE;
|
||||
|
||||
schSCManager = OpenSCManager( NULL, NULL, SC_MANAGER_ALL_ACCESS );
|
||||
if(!schSCManager) return(FALSE);
|
||||
if(RemoveDriver( schSCManager, sDriverShort )) ret = TRUE;
|
||||
CloseServiceHandle( schSCManager );
|
||||
return( ret );
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Exported stuff begins
|
||||
|
||||
int CdenableSysReadCdBytes( HANDLE h, DWORD start, DWORD count, char *buf )
|
||||
{
|
||||
HANDLE hDevice;
|
||||
int ret;
|
||||
DWORD nb;
|
||||
DWORD in_buffer[10];
|
||||
DWORD out_buffer[10];
|
||||
|
||||
ret = 0;
|
||||
|
||||
in_buffer[0] = (DWORD)h;
|
||||
in_buffer[1] = (DWORD)start;
|
||||
in_buffer[2] = (DWORD)count;
|
||||
in_buffer[3] = (DWORD)buf;
|
||||
out_buffer[0] = 0;
|
||||
|
||||
hDevice = CreateFile (sCompleteName,
|
||||
GENERIC_READ | GENERIC_WRITE,
|
||||
0,
|
||||
NULL,
|
||||
OPEN_EXISTING,
|
||||
FILE_ATTRIBUTE_NORMAL,
|
||||
NULL
|
||||
);
|
||||
|
||||
if (hDevice == ((HANDLE)-1)) {
|
||||
ret = 0;
|
||||
} else {
|
||||
if ( DeviceIoControl( hDevice,
|
||||
IOCTL_CDENABLE_READ,
|
||||
(LPVOID)in_buffer, 16,
|
||||
(LPVOID)out_buffer, 4,
|
||||
&nb, NULL ) )
|
||||
{
|
||||
if(out_buffer[0] != 0) ret = count;
|
||||
}
|
||||
CloseHandle (hDevice);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int CdenableSysReadCdSectors( HANDLE h, DWORD start, DWORD count, char *buf )
|
||||
{
|
||||
return( CdenableSysReadCdBytes( h, (start<<11), (count<<11), buf ) );
|
||||
}
|
||||
|
||||
int CdenableSysWriteCdBytes( HANDLE h, DWORD start, DWORD count, char *buf )
|
||||
{
|
||||
return( 0 );
|
||||
|
||||
/*
|
||||
HANDLE hDevice;
|
||||
int ret;
|
||||
DWORD nb;
|
||||
DWORD in_buffer[10];
|
||||
DWORD out_buffer[10];
|
||||
|
||||
ret = 0;
|
||||
|
||||
in_buffer[0] = (DWORD)h;
|
||||
in_buffer[1] = (DWORD)start;
|
||||
in_buffer[2] = (DWORD)count;
|
||||
in_buffer[3] = (DWORD)buf;
|
||||
out_buffer[0] = 0;
|
||||
|
||||
hDevice = CreateFile (sCompleteName,
|
||||
GENERIC_READ | GENERIC_WRITE,
|
||||
0,
|
||||
NULL,
|
||||
OPEN_EXISTING,
|
||||
FILE_ATTRIBUTE_NORMAL,
|
||||
NULL
|
||||
);
|
||||
|
||||
if (hDevice == ((HANDLE)-1)) {
|
||||
ret = 0;
|
||||
} else {
|
||||
if ( DeviceIoControl( hDevice,
|
||||
IOCTL_CDENABLE_WRITE,
|
||||
(LPVOID)in_buffer, 16,
|
||||
(LPVOID)out_buffer, 4,
|
||||
&nb, NULL ) )
|
||||
{
|
||||
if(out_buffer[0] != 0) ret = count;
|
||||
}
|
||||
CloseHandle (hDevice);
|
||||
}
|
||||
|
||||
return ret;
|
||||
*/
|
||||
}
|
||||
|
||||
int CdenableSysWriteCdSectors( HANDLE h, DWORD start, DWORD count, char *buf )
|
||||
{
|
||||
// return( CdenableSysWriteCdBytes( h, (start<<11), (count<<11), buf ) );
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
BOOL CdenableSysInstallStart(void)
|
||||
{
|
||||
return(start_driver());
|
||||
}
|
||||
|
||||
void CdenableSysStopRemove(void)
|
||||
{
|
||||
stop_driver();
|
||||
remove_driver();
|
||||
}
|
||||
|
||||
DWORD CdenableSysGetVersion( void )
|
||||
{
|
||||
HANDLE hDevice;
|
||||
DWORD ret;
|
||||
DWORD nb;
|
||||
DWORD out_buffer[10];
|
||||
|
||||
ret = 0;
|
||||
out_buffer[0] = 0;
|
||||
hDevice = CreateFile (sCompleteName,
|
||||
GENERIC_READ | GENERIC_WRITE,
|
||||
0,
|
||||
NULL,
|
||||
OPEN_EXISTING,
|
||||
FILE_ATTRIBUTE_NORMAL,
|
||||
NULL
|
||||
);
|
||||
if (hDevice == ((HANDLE)-1)) {
|
||||
ret = 0;
|
||||
} else {
|
||||
if ( DeviceIoControl( hDevice,
|
||||
IOCTL_CDENABLE_GET_VERSION,
|
||||
NULL, 0,
|
||||
(LPVOID)out_buffer, 4,
|
||||
&nb, NULL ) )
|
||||
{
|
||||
ret = out_buffer[0];
|
||||
}
|
||||
CloseHandle (hDevice);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
} //extern "C"
|
||||
#endif
|
||||
|
99
BasiliskII/src/Windows/cdenable/ntcd.h
Executable file
99
BasiliskII/src/Windows/cdenable/ntcd.h
Executable file
@ -0,0 +1,99 @@
|
||||
/*
|
||||
* ntcd.h - Interface to cdenable.sys driver
|
||||
*
|
||||
* Basilisk II (C) 1997-1999 Christian Bauer
|
||||
*
|
||||
* Windows platform specific code copyright (C) Lauri Pesonen
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
Installs the driver, if not already installed.
|
||||
Starts the driver, if not already running.
|
||||
|
||||
You can either always call "CdenableSysInstallStart" when your
|
||||
program fires up and "CdenableSysStopRemove" when it terminates,
|
||||
or just let the installation program call "CdenableSysInstallStart"
|
||||
and leave it always be present.
|
||||
|
||||
I recommend the latter option. Calling "CdenableSysInstallStart"
|
||||
always doesn't hurt anything, it will immediately return
|
||||
with success if the service is running.
|
||||
|
||||
Returns non-zero if installation/startup was succesfull,
|
||||
zero if anything failed.
|
||||
Returns non-zero also if the driver was already running.
|
||||
|
||||
The file "cdenable.sys" must already have been copied to
|
||||
the directory "System32\Drivers"
|
||||
*/
|
||||
|
||||
#ifndef _NT_CD_H_
|
||||
#define _NT_CD_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
BOOL CdenableSysInstallStart(void);
|
||||
|
||||
|
||||
/*
|
||||
Stops and removes the driver. See above.
|
||||
This must be called when new version of the driver is updated.
|
||||
*/
|
||||
void CdenableSysStopRemove(void);
|
||||
|
||||
|
||||
/*
|
||||
HANDLE h: returned from CreateFile ( "\\\\.\\X:", GENERIC_READ, ... );
|
||||
Returns the bytes actually read (==count), 0 on failure.
|
||||
NOTE: in my code, start and count are always aligned to
|
||||
sector boundaries (2048 bytes).
|
||||
I cannot guarantee that this works if they are not.
|
||||
Max read is 64 kb.
|
||||
Synchronous read, but quite fast.
|
||||
*/
|
||||
int CdenableSysReadCdBytes( HANDLE h, DWORD start, DWORD count, char *buf );
|
||||
|
||||
|
||||
/*
|
||||
Same as SysReadCdBytes, but "start" and "count" are in 2048 byte
|
||||
sectors.
|
||||
*/
|
||||
int CdenableSysReadCdSectors( HANDLE h, DWORD start, DWORD count, char *buf );
|
||||
|
||||
|
||||
/*
|
||||
Ditto for writing stuff.
|
||||
Not a cd of course but removable & hd media are supported now.
|
||||
*/
|
||||
int CdenableSysWriteCdBytes( HANDLE h, DWORD start, DWORD count, char *buf );
|
||||
int CdenableSysWriteCdSectors( HANDLE h, DWORD start, DWORD count, char *buf );
|
||||
|
||||
|
||||
/*
|
||||
Returns CDENABLE_CURRENT_VERSION (of the driver).
|
||||
*/
|
||||
DWORD CdenableSysGetVersion( void );
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
||||
#endif //_NT_CD_H_
|
Loading…
Reference in New Issue
Block a user