Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

419 lines
10 KiB

#include <nt.h>
#include <ntrtl.h>
#include <nturtl.h>
#include <windows.h>
#include "psapi.h"
#include <stddef.h>
BOOL
FindDeviceDriver(
LPVOID ImageBase,
PRTL_PROCESS_MODULE_INFORMATION Module
)
/*++
Routine Description:
This function retrieves the full pathname of the executable file
from which the specified module was loaded. The function copies the
null-terminated filename into the buffer pointed to by the
lpFilename parameter.
Routine Description:
ImageBase - Identifies the driver whose executable file name is being
requested.
Return Value:
A return value of FALSE indicates an error and extended
error status is available using the GetLastError function.
Arguments:
--*/
{
NTSTATUS Status;
DWORD cbModuleInformation, cbModuleInformationNew, NumberOfModules;
PRTL_PROCESS_MODULES pModuleInformation;
DWORD i, ReturnedLength;
//
// Set the buffer length and pointer to a fixed size for the first pass
//
cbModuleInformation = sizeof (RTL_PROCESS_MODULES) + 0x400;
pModuleInformation = NULL;
while (1) {
pModuleInformation = LocalAlloc (LMEM_FIXED, cbModuleInformation);
if (pModuleInformation == NULL) {
SetLastError (ERROR_NO_SYSTEM_RESOURCES);
return FALSE;
}
Status = NtQuerySystemInformation (SystemModuleInformation,
pModuleInformation,
cbModuleInformation,
&ReturnedLength);
NumberOfModules = pModuleInformation->NumberOfModules;
if (NT_SUCCESS(Status)) {
break;
} else {
LocalFree (pModuleInformation);
if (Status == STATUS_INFO_LENGTH_MISMATCH) {
ASSERT (cbModuleInformation >= sizeof (RTL_PROCESS_MODULES));
cbModuleInformationNew = FIELD_OFFSET (RTL_PROCESS_MODULES, Modules) +
NumberOfModules * sizeof (RTL_PROCESS_MODULE_INFORMATION);
ASSERT (cbModuleInformationNew >= sizeof (RTL_PROCESS_MODULES));
ASSERT (cbModuleInformationNew > cbModuleInformation);
if (cbModuleInformationNew <= cbModuleInformation) {
SetLastError (RtlNtStatusToDosError (Status));
return FALSE;
}
cbModuleInformation = cbModuleInformationNew;
} else {
SetLastError (RtlNtStatusToDosError (Status));
return FALSE;
}
}
}
for (i = 0; i < NumberOfModules; i++) {
if (pModuleInformation->Modules[i].ImageBase == ImageBase) {
*Module = pModuleInformation->Modules[i];
LocalFree (pModuleInformation);
return TRUE;
}
}
LocalFree (pModuleInformation);
SetLastError (ERROR_INVALID_HANDLE);
return FALSE;
}
BOOL
WINAPI
EnumDeviceDrivers(
LPVOID *lpImageBase,
DWORD cb,
LPDWORD lpcbNeeded
)
{
NTSTATUS Status;
DWORD cbModuleInformation, cbModuleInformationNew, NumberOfModules;
PRTL_PROCESS_MODULES pModuleInformation;
DWORD cpvMax;
DWORD i, ReturnedLength;
//
// Set the buffer length and pointer to a fixed size for the first pass
//
cbModuleInformation = sizeof (RTL_PROCESS_MODULES) + 0x400;
pModuleInformation = NULL;
while (1) {
pModuleInformation = LocalAlloc (LMEM_FIXED, cbModuleInformation);
if (pModuleInformation == NULL) {
SetLastError (ERROR_NO_SYSTEM_RESOURCES);
return FALSE;
}
Status = NtQuerySystemInformation (SystemModuleInformation,
pModuleInformation,
cbModuleInformation,
&ReturnedLength);
NumberOfModules = pModuleInformation->NumberOfModules;
if (NT_SUCCESS(Status)) {
break;
} else {
LocalFree (pModuleInformation);
if (Status == STATUS_INFO_LENGTH_MISMATCH) {
ASSERT (cbModuleInformation >= sizeof (RTL_PROCESS_MODULES));
cbModuleInformationNew = FIELD_OFFSET (RTL_PROCESS_MODULES, Modules) +
NumberOfModules * sizeof (RTL_PROCESS_MODULE_INFORMATION);
ASSERT (cbModuleInformationNew >= sizeof (RTL_PROCESS_MODULES));
ASSERT (cbModuleInformationNew > cbModuleInformation);
if (cbModuleInformationNew <= cbModuleInformation) {
SetLastError (RtlNtStatusToDosError (Status));
return FALSE;
}
cbModuleInformation = cbModuleInformationNew;
} else {
SetLastError (RtlNtStatusToDosError (Status));
return FALSE;
}
}
}
cpvMax = cb / sizeof(LPVOID);
for (i = 0; i < NumberOfModules; i++) {
if (i == cpvMax) {
break;
}
try {
lpImageBase[i] = pModuleInformation->Modules[i].ImageBase;
} except (EXCEPTION_EXECUTE_HANDLER) {
LocalFree (pModuleInformation);
SetLastError (RtlNtStatusToDosError (GetExceptionCode ()));
return FALSE;
}
}
try {
*lpcbNeeded = NumberOfModules * sizeof(LPVOID);
} except (EXCEPTION_EXECUTE_HANDLER) {
LocalFree (pModuleInformation);
SetLastError (RtlNtStatusToDosError (GetExceptionCode ()));
return FALSE;
}
LocalFree (pModuleInformation);
return TRUE;
}
DWORD
WINAPI
GetDeviceDriverFileNameW(
LPVOID ImageBase,
LPWSTR lpFilename,
DWORD nSize
)
/*++
Routine Description:
This function retrieves the full pathname of the executable file
from which the specified module was loaded. The function copies the
null-terminated filename into the buffer pointed to by the
lpFilename parameter.
Routine Description:
ImageBase - Identifies the driver whose executable file name is being
requested.
lpFilename - Points to the buffer that is to receive the filename.
nSize - Specifies the maximum number of characters to copy. If the
filename is longer than the maximum number of characters
specified by the nSize parameter, it is truncated.
Return Value:
The return value specifies the actual length of the string copied to
the buffer. A return value of zero indicates an error and extended
error status is available using the GetLastError function.
Arguments:
--*/
{
LPSTR lpstr;
DWORD cch;
DWORD cchT;
lpstr = (LPSTR) LocalAlloc (LMEM_FIXED, nSize);
if (lpstr == NULL) {
return(0);
}
cchT = cch = GetDeviceDriverFileNameA (ImageBase, lpstr, nSize);
if (!cch) {
LocalFree((HLOCAL) lpstr);
return 0;
}
if (cchT < nSize) {
//
// Include NULL terminator
//
cchT++;
}
if (!MultiByteToWideChar(CP_ACP, 0, lpstr, cchT, lpFilename, nSize)) {
cch = 0;
}
LocalFree((HLOCAL) lpstr);
return(cch);
}
DWORD
WINAPI
GetDeviceDriverFileNameA(
LPVOID ImageBase,
LPSTR lpFilename,
DWORD nSize
)
{
RTL_PROCESS_MODULE_INFORMATION Module;
DWORD cchT;
DWORD cch;
if (!FindDeviceDriver(ImageBase, &Module)) {
return(0);
}
cch = cchT = (DWORD) (strlen(Module.FullPathName) + 1);
if ( nSize < cch ) {
cch = nSize;
}
CopyMemory(lpFilename, Module.FullPathName, cch);
if (cch == cchT) {
cch--;
}
return(cch);
}
DWORD
WINAPI
GetDeviceDriverBaseNameW(
LPVOID ImageBase,
LPWSTR lpFilename,
DWORD nSize
)
/*++
Routine Description:
This function retrieves the full pathname of the executable file
from which the specified module was loaded. The function copies the
null-terminated filename into the buffer pointed to by the
lpFilename parameter.
Routine Description:
ImageBase - Identifies the driver whose executable file name is being
requested.
lpFilename - Points to the buffer that is to receive the filename.
nSize - Specifies the maximum number of characters to copy. If the
filename is longer than the maximum number of characters
specified by the nSize parameter, it is truncated.
Return Value:
The return value specifies the actual length of the string copied to
the buffer. A return value of zero indicates an error and extended
error status is available using the GetLastError function.
Arguments:
--*/
{
LPSTR lpstr;
DWORD cch;
DWORD cchT;
lpstr = (LPSTR) LocalAlloc(LMEM_FIXED, nSize);
if (lpstr == NULL) {
return(0);
}
cchT = cch = GetDeviceDriverBaseNameA(ImageBase, lpstr, nSize);
if (!cch) {
LocalFree((HLOCAL) lpstr);
return 0;
}
if (cchT < nSize) {
//
// Include NULL terminator
//
cchT++;
}
if (!MultiByteToWideChar(CP_ACP, 0, lpstr, cchT, lpFilename, nSize)) {
cch = 0;
}
LocalFree((HLOCAL) lpstr);
return(cch);
}
DWORD
WINAPI
GetDeviceDriverBaseNameA(
LPVOID ImageBase,
LPSTR lpFilename,
DWORD nSize
)
{
RTL_PROCESS_MODULE_INFORMATION Module;
DWORD cchT;
DWORD cch;
if (!FindDeviceDriver(ImageBase, &Module)) {
return(0);
}
cch = cchT = (DWORD) (strlen(Module.FullPathName + Module.OffsetToFileName) + 1);
if ( nSize < cch ) {
cch = nSize;
}
CopyMemory(lpFilename, Module.FullPathName + Module.OffsetToFileName, cch);
if (cch == cchT) {
cch--;
}
return(cch);
}