.data
szFormat	BYTE "%s %08lX",0
szCRLF		BYTE 0dh,0ah,0
.data?
hSCManager 	HANDLE ?
hService 	HANDLE ?
hDevice 	HANDLE ?
BuffRegisters DWORD ?
f_running	DWORD ?
ALIGN DWORD
_ss			SERVICE_STATUS <>

.code
DriverCall proc hWin:HWND

local acModulePath[MAX_PATH]:CHAR


	; Open a handle to the SC Manager database
	invoke OpenSCManager, NULL, NULL, SC_MANAGER_ALL_ACCESS
	.if eax==NULL
		invoke MessageBox, NULL, $CTA0("Can't connect to Service Control Manager."), NULL, MB_OK + MB_ICONSTOP
		mov eax,FALSE
		ret
	.endif
		
	mov hSCManager, eax
	
	push eax ;on se sert pas du dernier param... donc esp est discardé (cf.pop)
	invoke GetFullPathName, $CTA0("anti_rdtsc.sys"), sizeof acModulePath, addr acModulePath, esp
	pop eax ; par le pop eax
	
	; Install service
	invoke CreateService, hSCManager, $CTA0("anti_rdtsc"), $CTA0("anti_rdtsc"), \
		SERVICE_START + SERVICE_STOP + DELETE, SERVICE_KERNEL_DRIVER, SERVICE_DEMAND_START, \
		SERVICE_ERROR_IGNORE, addr acModulePath, NULL, NULL, NULL, NULL, NULL
		.if eax==NULL
			invoke MessageBox, NULL, $CTA0("Can't register driver."), NULL, MB_OK + MB_ICONSTOP
			invoke CloseService
			ret
		.endif
	
	mov hService, eax

		; Driver's DriverEntry procedure will be called
		invoke StartService, hService, 0, NULL
		.if eax==NULL
			invoke MessageBox, NULL, $CTA0("Can't start driver."), NULL, MB_OK + MB_ICONSTOP
			invoke CloseService
			ret
		.endif

			; Driver will receive I/O request packet (IRP) of type IRP_MJ_CREATE
			invoke CreateFile, $CTA0("\\\\.\\anti_rdtsc"), GENERIC_READ + GENERIC_WRITE, \
							0, NULL, OPEN_EXISTING, 0, NULL
			.if eax==INVALID_HANDLE_VALUE
				invoke MessageBox, NULL, $CTA0("Device is not present."), NULL, MB_ICONSTOP
				invoke CloseService
				ret
			.endif

			mov hDevice, eax

		invoke SendRequest,hWin
	
	mov f_running,TRUE ; service is running
	mov eax,TRUE ;everything ok
	ret
		
DriverCall endp
SendRequest PROC hWin:HWND

local abyOutBuffer[sizeof RegistersStruct]:BYTE
local dwBytesReturned:DWORD
local acRegisters[16d]:CHAR

	;zeromemory output buff
	invoke RtlZeroMemory,addr abyOutBuffer,sizeof abyOutBuffer

	; Driver will receive IRP of type IRP_MJ_DEVICE_CONTROL
	invoke DeviceIoControl, hDevice, IOCTL_GET_REGISTERS, NULL, 0, \
						addr abyOutBuffer, sizeof abyOutBuffer, addr dwBytesReturned, NULL

	.if ( eax != 0 ) && ( dwBytesReturned != 0 )
		invoke VirtualAlloc,NULL,1000h,MEM_COMMIT,PAGE_READWRITE
		mov BuffRegisters,eax
		xor ecx,ecx
		@@Loop:
		lea eax, abyOutBuffer
		mov ebx,[eax+ecx*4] ; ebx= registre
		mov edx,[pm_szRS+ecx*4] ; edx = string
		push ecx
		invoke wsprintf, addr acRegisters, addr szFormat ,edx , ebx
		invoke lstrcat,BuffRegisters,addr acRegisters
		invoke lstrcat,BuffRegisters,addr szCRLF
		pop ecx
		inc ecx
		cmp ecx,sizeof RegistersStruct/4
		jnz @@Loop
		
		invoke SetDlgItemText,hWin,IDC_EDT1,BuffRegisters
		invoke VirtualFree,BuffRegisters,NULL,MEM_RELEASE
	.else
		invoke MessageBox, NULL, $CTA0("Can't send control code to device."), NULL, MB_OK + MB_ICONSTOP
	.endif	
	
	ret

SendRequest endp
StopDriver PROC
	
	; Driver will receive IRP of type IRP_MJ_CLOSE
	.if hDevice != NULL
		invoke CloseHandle, hDevice
	.endif
	.if hService != NULL
		invoke ControlService, hService, SERVICE_CONTROL_STOP, addr _ss
	.endif
	
	invoke CloseService
	mov f_running,FALSE ; service is stopped
	ret

StopDriver endp
CloseService PROC
	
	.if hService != NULL
		invoke DeleteService,hService
		invoke CloseServiceHandle,hService
	.endif
	.if hSCManager != NULL
		invoke CloseServiceHandle, hSCManager
	.endif
	
	mov hService,NULL
	mov hSCManager,NULL
	mov eax,FALSE
		
	ret

CloseService endp