我有一个用 C 编写的内核驱动程序,它需要一个类型为 的文本PCWSTR
。什么是相当于发送控制代码的 Delphi 类型?我尝试使用以下代码发送但GetLastError
报告ERROR_NOACCESS
。如何解决?
program Driverloader;
{$APPTYPE CONSOLE}
{$R *.res}
uses
Windows,
WinSvc,
SysUtils;
function InstallAndStartDriver(DriverPath, DriverName: WideString; out DriverDevice: THandle): Boolean;
var
hSCManager, hService: THandle;
lpServiceArgVectors: PWideChar;
begin
Result := False;
hSCManager := 0;
hSCManager := OpenSCManagerW(nil, nil, SC_MANAGER_ALL_ACCESS);
if hSCManager <> 0 then
begin
try
Writeln('OpenSCManagerW() - OK');
hService := 0;
hService := CreateServiceW(hSCManager, PWideChar(DriverName), PWideChar(DriverName), SERVICE_ALL_ACCESS, SERVICE_KERNEL_DRIVER, SERVICE_DEMAND_START, SERVICE_ERROR_NORMAL, PWideChar(DriverPath), nil, nil, nil, nil, nil);
hService := 0;
lpServiceArgVectors := nil;
hService := OpenServiceW(hSCManager, PWideChar(DriverName), SERVICE_ALL_ACCESS);
if hService <> 0 then
begin
try
Writeln('OpenServiceW() - OK');
if StartServiceW(hService, 0, PWideChar(lpServiceArgVectors)) then
begin
Writeln('StartServiceW() - OK');
Result := True;
end;
finally
CloseServiceHandle(hService);
end;
end;
finally
CloseServiceHandle(hSCManager);
end;
end;
if Result the
begin
DriverDevice := CreateFileW(PWideChar('\\.\' + DriverName), GENERIC_READ or GENERIC_WRITE, 0, PSECURITY_DESCRIPTOR(nil), OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
Result := GetLastError() = ERROR_SUCCESS;
Writeln('CreateFileW() - ' + IntToStr(GetLastError));
end;
end;
function CTL_CODE(DeviceType, _Function, Method, Access: Cardinal): Cardinal;
begin
Result := (DeviceType shl 16) or (Access shl 14) or (_Function shl 2) or (Method);
end;
var
driver: THandle;
BytesReturned, IOCTL_PATH_DELETE: Cardinal;
szInput, szOutput: array[0..255] of WideChar;
begin
try
IOCTL_PATH_DELETE := CTL_CODE(FILE_DEVICE_UNKNOWN, $500, METHOD_BUFFERED, FILE_ANY_ACCESS);
lstrcpy(szInput, '\??\C:\Program Files\Software Folder');
if InstallAndStartDriver(IncludeTrailingPathDelimiter(GetCurrentDir) + 'MyDriver.sys', 'MyDriver', driver) then
begin
Writeln('InstallAndStartDriver() - OK');
Sleep(2000);
if not DeviceIOControl(driver, IOCTL_PATH_DELETE, PWideChar(szInput[0]), SizeOf(szInput), PWideChar(szOutput[0]), SizeOf(szOutput) * MAXBYTE, BytesReturned, nil) then
Writeln('DeviceIOControl() - Error: ' + IntToStr(GetLastError))
else
Writeln('Success! - ' + szOutput);
end;
except
on E: Exception do
Writeln(E.ClassName, ': ', E.Message);
end;
Readln;
end.
编辑
在内核驱动程序“Dispatch”方法上接收文本:
NTSTATUS DrvDispatch(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
{
PIO_STACK_LOCATION irpStack;
PVOID ioBuffer;
ULONG ioControlCode;
NTSTATUS ntStatus;
PCWSTR Path;
Irp->IoStatus.Status = STATUS_SUCCESS;
Irp->IoStatus.Information = 0;
irpStack = IoGetCurrentIrpStackLocation(Irp);
ioBuffer = Irp->AssociatedIrp.SystemBuffer;
switch (irpStack->MajorFunction) {
case IRP_MJ_DEVICE_CONTROL:
ioControlCode = irpStack->Parameters.DeviceIoControl.IoControlCode;
switch (ioControlCode) {
case IOCTL_PATH_DELETE: {
Path = *(PCWSTR*)ioBuffer; // <-- fails and stop here
dprintf("%s\n", Path);
break;
}
default:
Irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
break;
}
break;
}
ntStatus = Irp->IoStatus.Status;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return ntStatus;
}