| /* | |
| * ntcd.cpp - Interface to cdenable.sys driver | |
| * | |
| * Basilisk II (C) 1997-2008 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" | |
| extern "C" { | |
| #include <winioctl.h> | |
| #include <winsvc.h> | |
| #include "ntcd.h" | |
| #include "cdenable.h" | |
| static LPCTSTR sDriverShort = TEXT("cdenable"); | |
| static LPCTSTR sDriverLong = TEXT("System32\\Drivers\\cdenable.sys"); | |
| static LPCTSTR sCompleteName = TEXT("\\\\.\\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 | |