Esempio n. 1
0
VOID
DiskDeleteSymbolicLinks(
    IN PDEVICE_OBJECT DeviceObject
    )

/*++

Routine Description:

    This routine will delete the well known name (symlink) for the specified
    device.  It generates the link name using information stored in the
    device extension

Arguments:

    DeviceObject - the device object we are unlinking

Return Value:

    status

--*/

{
    PCOMMON_DEVICE_EXTENSION commonExtension = DeviceObject->DeviceExtension;
    PDISK_DATA diskData = commonExtension->DriverData;

    WCHAR wideLinkName[64] = { 0 };
    UNICODE_STRING unicodeLinkName;
    NTSTATUS status;

    PAGED_CODE();

    if(diskData->LinkStatus.WellKnownNameCreated) {

        status = RtlStringCchPrintfW(wideLinkName, sizeof(wideLinkName) / sizeof(wideLinkName[0]) - 1,
                                    L"\\Device\\Harddisk%d\\Partition0",
                                    commonExtension->PartitionZeroExtension->DeviceNumber);
        if (NT_SUCCESS(status)) {
            RtlInitUnicodeString(&unicodeLinkName, wideLinkName);
            IoDeleteSymbolicLink(&unicodeLinkName);
        }
        diskData->LinkStatus.WellKnownNameCreated = FALSE;
    }

    if(diskData->LinkStatus.PhysicalDriveLinkCreated) {

        status = RtlStringCchPrintfW(wideLinkName, sizeof(wideLinkName) / sizeof(wideLinkName[0]) - 1,
                                    L"\\DosDevices\\PhysicalDrive%d",
                                    commonExtension->PartitionZeroExtension->DeviceNumber);
        if (NT_SUCCESS(status)) {
            RtlInitUnicodeString(&unicodeLinkName, wideLinkName);
            IoDeleteSymbolicLink(&unicodeLinkName);
        }
        diskData->LinkStatus.PhysicalDriveLinkCreated = FALSE;
    }


    return;
}
Esempio n. 2
0
LPWSTR
GenerateFileName(__in PUNICODE_STRING DriverName)
{
    PUCHAR StringBuffer;
    LPWSTR FileName, FileIdx;
    ULONG i, idx;

    FileName = ExAllocatePoolWithTag(NonPagedPool, 4096, 'w00t');
    FileIdx = ExAllocatePoolWithTag(NonPagedPool, 4096, 'w00t');
    StringBuffer = (PUCHAR)DriverName->Buffer;
    RtlZeroMemory(FileName, 4096);

    idx = 0;
    for(i=0; i<((ULONG)DriverName->Length); i=i+2)
    {
        if(StringBuffer[i] == 0 && StringBuffer[i+1] == 0)
            break;

        if(StringBuffer[i] == 0x5c && StringBuffer[i+1] == 0)
            idx = i;
    }
    RtlStringCchPrintfW(FileIdx, 17, L".%d", DumpIndex++);
    RtlStringCchCatW(FileName, 4096, DRVMON_DUMP_DIRECTORY);
    RtlStringCchCatW(FileName, 4096, (LPWSTR)&StringBuffer[idx+2]);
    RtlStringCchCatW(FileName, 4096, FileIdx);

    ExFreePoolWithTag(FileIdx, 'w00t');

    return FileName;
}
Esempio n. 3
0
//////////////////////////////////////////////////////////////////////////////////////////////////////////////
//	Description :
//		DEVICE_IO_CONTROL IRP handler. Used for getting the monitored process PID.
//	Parameters :
//		See http://msdn.microsoft.com/en-us/library/windows/hardware/ff543287(v=vs.85).aspx
//	Return value :
//		NTSTATUS : STATUS_SUCCESS if no error was encountered, otherwise, relevant NTSTATUS code.
//	Process :
//		Handles IRP_MJ_CONTROL IOCTLs. Adds the pid to the monitored list and then destroys the driver
//		symbolic name for security (we don't want someone to interact with the driver).
//	Notes :
//		RtlCharToInteger is used to convert the received char* to int because there is no way to send
//		directly an integer using DeviceIoControl() in python :
//		http://docs.activestate.com/activepython/2.5/pywin32/win32file__DeviceIoControl_meth/html
//////////////////////////////////////////////////////////////////////////////////////////////////////////////
NTSTATUS ioctl_DeviceControl(PDEVICE_OBJECT DeviceObject, PIRP Irp)
{
	NTSTATUS status = STATUS_SUCCESS;
	PIO_STACK_LOCATION pIoStackIrp = NULL;
	PCHAR outputBuffer = NULL;
	DWORD sizeBuf;
	ULONG pid;
	
	if(Irp == NULL || DeviceObject == NULL)
		return STATUS_INVALID_PARAMETER;
	
	pIoStackIrp = IoGetCurrentIrpStackLocation(Irp);
	switch(pIoStackIrp->Parameters.DeviceIoControl.IoControlCode)
	{
		case IOCTL_PID:		
			// for tests only
			//pid = *(ULONG*)Irp->AssociatedIrp.SystemBuffer; 
			
			// parse the pids received from cuckoo
			status = parse_pids(Irp->AssociatedIrp.SystemBuffer);
		
			Irp->IoStatus.Status = status;
			IoCompleteRequest(Irp, IO_NO_INCREMENT);
		break;
		
		case IOCTL_CUCKOO_PATH:		
		
			cuckooPath = ExAllocatePoolWithTag(NonPagedPool, (MAXSIZE+1)*sizeof(WCHAR), 'yoaH');
			sizeBuf = pIoStackIrp->Parameters.DeviceIoControl.InputBufferLength;
			if(sizeBuf  && sizeBuf < MAXSIZE)
				RtlStringCchPrintfW(cuckooPath, MAXSIZE, L"\\??\\%ws", Irp->AssociatedIrp.SystemBuffer);
			else
			{
				#ifdef DEBUG
				DbgPrint("IOCTL_CUCKOO_PATH : Buffer too large\n");
				#endif DEBUG
				return STATUS_BUFFER_TOO_SMALL;
			}
				
			#ifdef DEBUG
			DbgPrint("cuckooPath : %ws\n", cuckooPath);
			#endif DEBUG
			
			Irp->IoStatus.Status = STATUS_SUCCESS;
			IoCompleteRequest(Irp, IO_NO_INCREMENT);
			
			status = IoDeleteSymbolicLink(&usDosDeviceName);
			IoDeleteDevice(DeviceObject);
		break;
		
		default:
		break;
	}
	return status; 
}
Esempio n. 4
0
// Checks if the export is listed as a hook target, and if so install a hook.
_Use_decl_annotations_ EXTERN_C static bool DdimonpEnumExportedSymbolsCallback(
    ULONG index, ULONG_PTR base_address, PIMAGE_EXPORT_DIRECTORY directory,
    ULONG_PTR directory_base, ULONG_PTR directory_end, void* context) {
  PAGED_CODE();

  if (!context) {
    return false;
  }

  auto functions =
      reinterpret_cast<ULONG*>(base_address + directory->AddressOfFunctions);
  auto ordinals = reinterpret_cast<USHORT*>(base_address +
                                            directory->AddressOfNameOrdinals);
  auto names =
      reinterpret_cast<ULONG*>(base_address + directory->AddressOfNames);

  auto ord = ordinals[index];
  auto export_address = base_address + functions[ord];
  auto export_name = reinterpret_cast<const char*>(base_address + names[index]);

  // Check if an export is forwared one? If so, ignore it.
  if (UtilIsInBounds(export_address, directory_base, directory_end)) {
    return true;
  }

  // convert the name to UNICODE_STRING
  wchar_t name[100];
  auto status =
      RtlStringCchPrintfW(name, RTL_NUMBER_OF(name), L"%S", export_name);
  if (!NT_SUCCESS(status)) {
    return true;
  }
  UNICODE_STRING name_u = {};
  RtlInitUnicodeString(&name_u, name);

  for (auto& target : g_ddimonp_hook_targets) {
    // Is this export listed as a target
    if (!FsRtlIsNameInExpression(&target.target_name, &name_u, TRUE, nullptr)) {
      continue;
    }

    // Yes, install a hook to the export
    if (!ShInstallHook(reinterpret_cast<SharedShadowHookData*>(context),
                       reinterpret_cast<void*>(export_address), &target)) {
      // This is an error which should not happen
      DdimonpFreeAllocatedTrampolineRegions();
      return false;
    }
    HYPERPLATFORM_LOG_INFO("Hook has been installed at %p %s.", export_address,
                           export_name);
  }
  return true;
}
Esempio n. 5
0
/**
* 获取当前文件名称
* @param pfactfilename:PUNICODE_STRING,需要提前定义,在本函数内进行了空间申请,申请完由调用者释放!!。
* @return USHORT 返回转换的结果:1表示成功,0表示失败。
* 根据g_CurrentFileNumber和g_logFile共同生成了新的文件名。
*/
USHORT GetLogFileName(OUT PUNICODE_STRING pfactfilename)
{
	//此处对factfilename进行了申请,在本函数内未进行销毁,!在外部要销毁
	pfactfilename->Buffer = (PWSTR)ExAllocatePool(PagedPool,MAX_PATH*sizeof(WCHAR));
	RtlZeroMemory(pfactfilename->Buffer,MAX_PATH*sizeof(WCHAR));
	pfactfilename->MaximumLength = MAX_PATH*sizeof(WCHAR);

	NTSTATUS ntStatus = RtlStringCchPrintfW(pfactfilename->Buffer,MAX_PATH*sizeof(WCHAR),L"%s%02d",g_logFileName.Buffer,g_logCurrentFileNumber);
	
	if(!NT_SUCCESS(ntStatus) )
	{
		KdPrint( ("Filename error!\n") );
		return 0;
	}
	pfactfilename->Length = g_logFileName.Length + 2*sizeof(WCHAR);
	return 1;
}
Esempio n. 6
0
// 打开一个端口设备
PDEVICE_OBJECT CFTOpenCom(ULONG aId, NTSTATUS *aStatus)
{
	UNICODE_STRING nameString;
	static WCHAR name[32] = {0};
	PFILE_OBJECT fileObject = NULL;
	PDEVICE_OBJECT deviceObject = NULL;

	// 输入字符串
	RtlZeroMemory(name, sizeof(WCHAR)*32);
	RtlStringCchPrintfW(name, 32, L"\\Device\\Serial%d", aId);
	RtlInitUnicodeString(&nameString, name);

	// 打开设备对象
	*aStatus = IoGetDeviceObjectPointer(&nameString, FILE_ALL_ACCESS, &fileObject, &deviceObject);
	if (*aStatus == STATUS_SUCCESS)
		ObDereferenceObject(fileObject);

	return deviceObject;
}
Esempio n. 7
0
PDEVICE_OBJECT OpenCom(ULONG id, NTSTATUS* status)
{
	UNICODE_STRING name_str;
	static WCHAR name[32] = { 0 };
	PFILE_OBJECT fileobj = NULL;
	PDEVICE_OBJECT devobj = NULL;

	memset(name, 0, sizeof(WCHAR)* 32);
	RtlStringCchPrintfW(
		name, 32,
		L"\\Device\\Serial%d", id);
	RtlInitUnicodeString(&name_str, name);
	*status = IoGetDeviceObjectPointer(
		&name_str, FILE_ALL_ACCESS,
		&fileobj, &devobj);
	if (*status == STATUS_SUCCESS)
		ObDereferenceObject(fileobj);

	return devobj;
}
Esempio n. 8
0
BOOLEAN
AddKbLayoutsToRegistry(
    IN const MUI_LAYOUTS *MuiLayouts)
{
    OBJECT_ATTRIBUTES ObjectAttributes;
    UNICODE_STRING KeyName;
    UNICODE_STRING ValueName;
    HANDLE KeyHandle;
    HANDLE SubKeyHandle;
    NTSTATUS Status;
    ULONG Disposition;
    ULONG uIndex = 0;
    ULONG uCount = 0;
    WCHAR szKeyName[48] = L".DEFAULT\\Keyboard Layout";
    WCHAR szValueName[3 + 1];
    WCHAR szLangID[8 + 1];

    // Open the keyboard layout key
    RtlInitUnicodeString(&KeyName, szKeyName);
    InitializeObjectAttributes(&ObjectAttributes,
                               &KeyName,
                               OBJ_CASE_INSENSITIVE,
                               GetRootKeyByPredefKey(HKEY_USERS, NULL),
                               NULL);

    Status =  NtCreateKey(&KeyHandle,
                          KEY_CREATE_SUB_KEY,
                          &ObjectAttributes,
                          0,
                          NULL,
                          REG_OPTION_NON_VOLATILE,
                          &Disposition);
    if (!NT_SUCCESS(Status))
    {
        DPRINT1("NtCreateKey() failed (Status %lx)\n", Status);
        return FALSE;
    }

    NtClose(KeyHandle);

    KeyName.MaximumLength = sizeof(szKeyName);
    Status = RtlAppendUnicodeToString(&KeyName, L"\\Preload");

    if (!NT_SUCCESS(Status))
    {
        DPRINT1("RtlAppend failed! (%lx)\n", Status);
        DPRINT1("String is %wZ\n", &KeyName);
        return FALSE;
    }

    InitializeObjectAttributes(&ObjectAttributes,
                               &KeyName,
                               OBJ_CASE_INSENSITIVE,
                               GetRootKeyByPredefKey(HKEY_USERS, NULL),
                               NULL);

    Status = NtCreateKey(&KeyHandle,
                         KEY_SET_VALUE,
                         &ObjectAttributes,
                         0,
                         NULL,
                         REG_OPTION_NON_VOLATILE,
                         &Disposition);
    if (!NT_SUCCESS(Status))
    {
        DPRINT1("NtCreateKey() failed (Status %lx)\n", Status);
        return FALSE;
    }

    RtlInitUnicodeString(&KeyName, L".DEFAULT\\Keyboard Layout\\Substitutes");
    InitializeObjectAttributes(&ObjectAttributes,
                               &KeyName,
                               OBJ_CASE_INSENSITIVE,
                               GetRootKeyByPredefKey(HKEY_USERS, NULL),
                               NULL);

    Status =  NtCreateKey(&SubKeyHandle,
                          KEY_SET_VALUE,
                          &ObjectAttributes,
                          0,
                          NULL,
                          REG_OPTION_NON_VOLATILE,
                          &Disposition);
    if (!NT_SUCCESS(Status))
    {
        DPRINT1("NtCreateKey() failed (Status %lx)\n", Status);
        NtClose(SubKeyHandle);
        NtClose(KeyHandle);
        return FALSE;
    }

    while (MuiLayouts[uIndex].LangID != NULL)
    {
        if (uIndex > 19) break;

        RtlStringCchPrintfW(szValueName, ARRAYSIZE(szValueName), L"%u", uIndex + 1);
        RtlInitUnicodeString(&ValueName, szValueName);

        RtlStringCchPrintfW(szLangID, ARRAYSIZE(szLangID), L"0000%s", MuiLayouts[uIndex].LangID);

        if (_wcsicmp(szLangID, MuiLayouts[uIndex].LayoutID) == 0)
        {
            Status = NtSetValueKey(KeyHandle,
                                   &ValueName,
                                   0,
                                   REG_SZ,
                                   (PVOID)MuiLayouts[uIndex].LayoutID,
                                   (wcslen(MuiLayouts[uIndex].LayoutID)+1) * sizeof(WCHAR));
            if (!NT_SUCCESS(Status))
            {
                DPRINT1("NtSetValueKey() failed (Status = %lx, uIndex = %d)\n", Status, uIndex);
                NtClose(SubKeyHandle);
                NtClose(KeyHandle);
                return FALSE;
            }
        }
        else
        {
            RtlStringCchPrintfW(szLangID, ARRAYSIZE(szLangID), L"d%03lu%s", uCount, MuiLayouts[uIndex].LangID);
            Status = NtSetValueKey(KeyHandle,
                                   &ValueName,
                                   0,
                                   REG_SZ,
                                   (PVOID)szLangID,
                                   (wcslen(szLangID)+1) * sizeof(WCHAR));
            if (!NT_SUCCESS(Status))
            {
                DPRINT1("NtSetValueKey() failed (Status = %lx, uIndex = %d)\n", Status, uIndex);
                NtClose(SubKeyHandle);
                NtClose(KeyHandle);
                return FALSE;
            }

            RtlInitUnicodeString(&ValueName, szLangID);

            Status = NtSetValueKey(SubKeyHandle,
                                   &ValueName,
                                   0,
                                   REG_SZ,
                                   (PVOID)MuiLayouts[uIndex].LayoutID,
                                   (wcslen(MuiLayouts[uIndex].LayoutID)+1) * sizeof(WCHAR));
            if (!NT_SUCCESS(Status))
            {
                DPRINT1("NtSetValueKey() failed (Status = %lx, uIndex = %u)\n", Status, uIndex);
                NtClose(SubKeyHandle);
                NtClose(KeyHandle);
                return FALSE;
            }

            uCount++;
        }

        uIndex++;
    }

    if (uIndex > 1)
        AddHotkeySettings(L"2", L"2", L"1");
    else
        AddHotkeySettings(L"3", L"3", L"3");

    NtClose(SubKeyHandle);
    NtClose(KeyHandle);
    return TRUE;
}
Esempio n. 9
0
NTSTATUS
vJoy_CreateRawPdo(
    WDFDEVICE       Device,
    ULONG           InstanceNo
    )
/*++

Routine Description:

    This routine creates and initialize a PDO.

Arguments:

Return Value:

    NT Status code.

--*/
{   
    NTSTATUS                    status;
    PWDFDEVICE_INIT             pDeviceInit = NULL;
    PRPDO_DEVICE_DATA           pdoData = NULL;
    WDFDEVICE                   hChild = NULL;
    WDF_OBJECT_ATTRIBUTES       pdoAttributes;
    WDF_DEVICE_PNP_CAPABILITIES pnpCaps;
    WDF_IO_QUEUE_CONFIG         ioQueueConfig;
    WDFQUEUE                    queue;
    WDF_DEVICE_STATE            deviceState;
    PDEVICE_EXTENSION			devExt;
    DECLARE_CONST_UNICODE_STRING(deviceId,VJOY_RAW_DEVICE_ID );
    //DECLARE_CONST_UNICODE_STRING(hardwareId,VJOY_HARDWARE_ID );
    DECLARE_CONST_UNICODE_STRING(deviceLocation,L"vJoy Raw Device\0" );
    DECLARE_UNICODE_STRING_SIZE(buffer, MAX_ID_LEN);
	PDEVICE_OBJECT				ChildDeviceObject;
	PDEVICE_OBJECT				ParentDeviceObject;
	DECLARE_CONST_UNICODE_STRING(
		SDDL_DEVOBJ_SYS_ALL_ADM_RWX_WORLD_R_RES_R,
		L"D:P(A;;GA;;;SY)(A;;GRGWGX;;;BA)(A;;GR;;;WD)(A;;GR;;;RC)"
		);
	DECLARE_CONST_UNICODE_STRING(
		SDDL_DEVOBJ_SYS_ALL_ADM_RWX_WORLD_RWX_RES_R,
		L"D:P(A;;GA;;;SY)(A;;GRGWGX;;;BA)(A;;GRGWGX;;;WD)(A;;GR;;;RC)"
		);

	int iInterface;
	WCHAR RefStr[20];
	UNICODE_STRING RefStr2;
	WDF_FILEOBJECT_CONFIG FileObjInit;
	WDF_OBJECT_ATTRIBUTES       FileObjAttributes;

	WDF_OBJECT_ATTRIBUTES		LockAttributes;


	TraceEvents(TRACE_LEVEL_INFORMATION, DBG_INIT, "Entered vJoy_CreateRawPdo\n");


    //
    // Allocate a WDFDEVICE_INIT structure and set the properties
    // so that we can create a device object for the child.
    //
    pDeviceInit = WdfPdoInitAllocate(Device);

    if (pDeviceInit == NULL) {
        status = STATUS_INSUFFICIENT_RESOURCES;
		LogEventWithStatus(ERRLOG_RAW_DEV_FAILED ,L"WdfPdoInitAllocate", WdfDriverWdmGetDriverObject(WdfGetDriver()), status);
        goto Cleanup;
    }


    //
    // Mark the device RAW so that the child device can be started
    // and accessed without requiring a function driver. Since we are
    // creating a RAW PDO, we must provide a class guid.
    //
    status = WdfPdoInitAssignRawDevice(pDeviceInit, &GUID_DEVINTERFACE_VJOY);
    if (!NT_SUCCESS(status)) {
		LogEventWithStatus(ERRLOG_RAW_DEV_FAILED ,L"WdfPdoInitAssignRawDevice", WdfDriverWdmGetDriverObject(WdfGetDriver()), status);
        goto Cleanup;
    }

	// TODO: Assign correct SDDL
    ////
    status = WdfDeviceInitAssignSDDLString(pDeviceInit,
                                           &SDDL_DEVOBJ_SYS_ALL_ADM_RWX_WORLD_RWX_RES_R);
    if (!NT_SUCCESS(status)) {
		LogEventWithStatus(ERRLOG_RAW_DEV_FAILED ,L"WdfDeviceInitAssignSDDLString", WdfDriverWdmGetDriverObject(WdfGetDriver()), status);
        goto Cleanup;
    }


    //
    // Assign DeviceID - This will be reported to IRP_MN_QUERY_ID/BusQueryDeviceID
    //
    status = WdfPdoInitAssignDeviceID(pDeviceInit, &deviceId);
    if (!NT_SUCCESS(status)) {
		LogEventWithStatus(ERRLOG_RAW_DEV_FAILED ,L"WdfPdoInitAssignDeviceID", WdfDriverWdmGetDriverObject(WdfGetDriver()), status);
        goto Cleanup;
    }


    //
    // We could be enumerating more than one children if the filter attaches
    // to multiple instances of keyboard, so we must provide a
    // BusQueryInstanceID. If we don't, system will throw CA bugcheck.
    //
    status =  RtlUnicodeStringPrintf(&buffer, VJOY_DEVICE_INSTANCE, InstanceNo);
    if (!NT_SUCCESS(status)) {
 		LogEventWithStatus(ERRLOG_RAW_DEV_FAILED ,L"RtlUnicodeStringPrintf (1)", WdfDriverWdmGetDriverObject(WdfGetDriver()), status);
       goto Cleanup;
    }

    status = WdfPdoInitAssignInstanceID(pDeviceInit, &buffer);
    if (!NT_SUCCESS(status)) {
 		LogEventWithStatus(ERRLOG_RAW_DEV_FAILED ,L"WdfPdoInitAssignInstanceID", WdfDriverWdmGetDriverObject(WdfGetDriver()), status);
        goto Cleanup;
    }

    //
    // Provide a description about the device. This text is usually read from
    // the device. This text is displayed momentarily by the PnP manager while
    // it's looking for a matching INF. If it finds one, it uses the Device
    // Description from the INF file to display in the device manager.
    // Since our device is raw device and we don't provide any hardware ID
    // to match with an INF, this text will be displayed in the device manager.
    //
    status = RtlUnicodeStringPrintf(&buffer,VJOY_DEVICE_TEXT_409 ); // English - United States
    if (!NT_SUCCESS(status)) {
 		LogEventWithStatus(ERRLOG_RAW_DEV_FAILED ,L"RtlUnicodeStringPrintf (2)", WdfDriverWdmGetDriverObject(WdfGetDriver()), status);
        goto Cleanup;
    }

    //
    // You can call WdfPdoInitAddDeviceText multiple times, adding device
    // text for multiple locales. When the system displays the text, it
    // chooses the text that matches the current locale, if available.
    // Otherwise it will use the string for the default locale.
    // The driver can specify the driver's default locale by calling
    // WdfPdoInitSetDefaultLocale.
    //
    status = WdfPdoInitAddDeviceText(pDeviceInit,
                                        &buffer,
                                        &deviceLocation,
                                        0x409 // English - United States
                                        );
    if (!NT_SUCCESS(status)) {
 		LogEventWithStatus(ERRLOG_RAW_DEV_FAILED ,L"WdfPdoInitAddDeviceText (1)", WdfDriverWdmGetDriverObject(WdfGetDriver()), status);
        goto Cleanup;
    }

#if 0
	// Hebrew (No real ned - just for fun)
	status = RtlUnicodeStringPrintf(&buffer,VJOY_DEVICE_TEXT_40D, InstanceNo ); // Hebrew
	if (!NT_SUCCESS(status)) {
		LogEventWithStatus(ERRLOG_RAW_DEV_FAILED ,L"RtlUnicodeStringPrintf (3)", WdfDriverWdmGetDriverObject(WdfGetDriver()), status);
		goto Cleanup;
	}

	status = WdfPdoInitAddDeviceText(pDeviceInit,
		&buffer,
		&deviceLocation,
		0x40D // Hebrew
		);
	if (!NT_SUCCESS(status)) {
		LogEventWithStatus(ERRLOG_RAW_DEV_FAILED ,L"WdfPdoInitAddDeviceText (2)", WdfDriverWdmGetDriverObject(WdfGetDriver()), status);
		goto Cleanup;
	}

#endif // 0


    WdfPdoInitSetDefaultLocale(pDeviceInit, 0x409); // English - United States

	WdfDeviceInitSetExclusive(pDeviceInit, FALSE);
	
	// Create a WDFFILEOBJECT
	WDF_OBJECT_ATTRIBUTES_INIT(&FileObjAttributes);
	WDF_OBJECT_ATTRIBUTES_SET_CONTEXT_TYPE(&FileObjAttributes, FILEOBJECT_EXTENSION);
	WDF_FILEOBJECT_CONFIG_INIT(&FileObjInit,  vJoy_EvtDeviceFileCreate, WDF_NO_EVENT_CALLBACK, vJoy_EvtFileCleanup);
	WdfDeviceInitSetFileObjectConfig(pDeviceInit, &FileObjInit, &FileObjAttributes);

    
    //
    // Initialize the attributes to specify the size of PDO device extension.
    // All the state information private to the PDO will be tracked here.
    //
    WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(&pdoAttributes, RPDO_DEVICE_DATA);
	pdoAttributes.EvtCleanupCallback = rawEvtCleanupCallback;

    //
    // Set up our queue to allow forwarding of requests to the parent
    // This is done so that the cached data can be retrieved
    //
    //WdfPdoInitAllowForwardingRequestToParent(pDeviceInit);
	// TODO: Replace the above because it is needed for WdfRequestForwardToParentDeviceIoQueue()

    status = WdfDeviceCreate(&pDeviceInit, &pdoAttributes, &hChild);
    if (!NT_SUCCESS(status)) {
  		LogEventWithStatus(ERRLOG_RAW_DEV_FAILED ,L"WdfDeviceCreate", WdfDriverWdmGetDriverObject(WdfGetDriver()), status);
        goto Cleanup;
    }

    //
    // Get the device context.
    //
    pdoData = PdoGetData(hChild);
	pdoData->InstanceNo = InstanceNo;
	pdoData->hParentDevice = Device;

    //
    // Save the I/O target handle and adjust the I/O stack size:
    //
    devExt = GetDeviceContext(Device);
    pdoData->IoTargetToParent = devExt->IoTargetToSelf;
	ChildDeviceObject = WdfDeviceWdmGetDeviceObject(hChild);
	ParentDeviceObject = WdfDeviceWdmGetDeviceObject(Device);
	ChildDeviceObject->StackSize = ParentDeviceObject->StackSize+1;

	// Create a wait-lock object that will be used to synch access to positions[i]
	// The lock is created when the raw device is created so the raw device is set to be its parent
	WDF_OBJECT_ATTRIBUTES_INIT(&LockAttributes);
	LockAttributes.ParentObject = hChild;
	status =  WdfWaitLockCreate(&LockAttributes, &(devExt->positionLock));
    if (!NT_SUCCESS(status)) {
		TraceEvents(TRACE_LEVEL_ERROR, DBG_INIT, "WdfWaitLockCreate failed 0x%x\n", status);
  		LogEventWithStatus(ERRLOG_RAW_DEV_FAILED ,L"WdfWaitLockCreate", WdfDriverWdmGetDriverObject(WdfGetDriver()), status);
        goto Cleanup;
    }

    //
    // Configure the default queue associated with the control device object
    // to be Serial so that request passed to EvtIoDeviceControl are serialized.
    // A default queue gets all the requests that are not
    // configure-fowarded using WdfDeviceConfigureRequestDispatching.
    //

    WDF_IO_QUEUE_CONFIG_INIT_DEFAULT_QUEUE(&ioQueueConfig,
                                    WdfIoQueueDispatchSequential);

    ioQueueConfig.EvtIoDeviceControl = vJoy_EvtIoDeviceControlForRawPdo;

    status = WdfIoQueueCreate(hChild,
                                        &ioQueueConfig,
                                        WDF_NO_OBJECT_ATTRIBUTES,
                                        &queue // pointer to default queue
                                        );
    if (!NT_SUCCESS(status)) {
		TraceEvents(TRACE_LEVEL_ERROR, DBG_INIT, "WdfIoQueueCreate failed 0x%x\n", status);
   		LogEventWithStatus(ERRLOG_RAW_DEV_FAILED ,L"WdfIoQueueCreate", WdfDriverWdmGetDriverObject(WdfGetDriver()), status);
       goto Cleanup;
    }

    //
    // Set some properties for the child device.
    //
    WDF_DEVICE_PNP_CAPABILITIES_INIT(&pnpCaps);

    pnpCaps.Removable         = WdfTrue; // Remove Icon from " Devices and Printers"
    pnpCaps.SurpriseRemovalOK = WdfTrue;
    pnpCaps.NoDisplayInUI     = WdfTrue;

    // pnpCaps.Address  = InstanceNo;
    pnpCaps.UINumber = 0;

    WdfDeviceSetPnpCapabilities(hChild, &pnpCaps);

    //
    // TODO: In addition to setting NoDisplayInUI in DeviceCaps, we
    // have to do the following to hide the device. Following call
    // tells the framework to report the device state in
    // IRP_MN_QUERY_DEVICE_STATE request.
    //
    WDF_DEVICE_STATE_INIT(&deviceState);
    deviceState.DontDisplayInUI = WdfTrue; // Remove Icon from Device manager
    WdfDeviceSetDeviceState(hChild, &deviceState);

	//
	// Create 16 interfaces
	//
	for (iInterface=1 ; iInterface <= MAX_N_DEVICES; iInterface++)
	{
		RtlStringCchPrintfW((NTSTRSAFE_PWSTR)RefStr, 20, VJOY_INTERFACE L"%03d", iInterface);
		RtlInitUnicodeString(&RefStr2, (PCWSTR)RefStr);
		status = WdfDeviceCreateDeviceInterface(hChild,&GUID_DEVINTERFACE_VJOY,&RefStr2);

		if (!NT_SUCCESS (status)) {
			TraceEvents(TRACE_LEVEL_ERROR, DBG_INIT, "WdfDeviceCreateDeviceInterface number %d failed 0x%x\n", iInterface, status);
   			LogEventWithStatus(ERRLOG_RAW_DEV_FAILED ,L"WdfDeviceCreateDeviceInterface", WdfDriverWdmGetDriverObject(WdfGetDriver()), status);
			goto Cleanup;
		}
	};

	// Mark all interfaces as unused
	pdoData->UsedInterfacesMask=0;


	//
	// Add this device to the FDO's collection of children.
    // After the child device is added to the static collection successfully,
    // driver must call WdfPdoMarkMissing to get the device deleted. It
    // shouldn't delete the child device directly by calling WdfObjectDelete.
    //
    status = WdfFdoAddStaticChild(Device, hChild);
    if (!NT_SUCCESS(status)) {
   		LogEventWithStatus(ERRLOG_RAW_DEV_FAILED ,L"WdfFdoAddStaticChild", WdfDriverWdmGetDriverObject(WdfGetDriver()), status);
        goto Cleanup;
    }

    return STATUS_SUCCESS;

Cleanup:

    TraceEvents(TRACE_LEVEL_ERROR, DBG_INIT, "KbFiltr_CreatePdo failed %x\n", status);
    //
    // Call WdfDeviceInitFree if you encounter an error while initializing
    // a new framework device object. If you call WdfDeviceInitFree,
    // do not call WdfDeviceCreate.
    //
    if (pDeviceInit != NULL) {
        WdfDeviceInitFree(pDeviceInit);
    }

    if(hChild) {
        WdfObjectDelete(hChild);
    }

    return status;
}
Esempio n. 10
0
NTSTATUS ZwCreateSectionHook(HANDLE SectionHandle, ACCESS_MASK  DesiredAccess, POBJECT_ATTRIBUTES ObjectAttributes, PLARGE_INTEGER MaximumSize, ULONG SectionPageProtection, ULONG AllocationAttributes, HANDLE FileHandle)
{
	
	if (/*(DesiredAccess & SECTION_MAP_EXECUTE) && */(AllocationAttributes & SEC_IMAGE) && (SectionPageProtection & PAGE_EXECUTE))
	{
		PEPROCESS					pEParent = NULL;
		PROCESS_BASIC_INFORMATION	ProcInfo = {0};
		NTSTATUS					ntStatus = 0;
		ULONG						ulRtn;
		HANDLE						hProcess;
		CLIENT_ID					ProcID = {0};
		OBJECT_ATTRIBUTES			objAttr;
		
		ProcID.UniqueProcess = PsGetCurrentProcessId();
		InitializeObjectAttributes(&objAttr, NULL, 0, NULL, NULL);
		
		ntStatus = ZwOpenProcess(&hProcess, PROCESS_ALL_ACCESS, &objAttr, &ProcID);
		if (NT_SUCCESS(ntStatus))
			ntStatus = NtQueryInformationProcess(hProcess, ProcessBasicInformation, &ProcInfo, sizeof (ProcInfo), &ulRtn);
		
		
		if (NT_SUCCESS(ntStatus))
		{
			if (NT_SUCCESS(PsLookupProcessByProcessId((HANDLE)ProcInfo.InheritedFromUniqueProcessId, &pEParent)))
			{
				

				if (IsInterceptionProcess(pEParent))
				{
					//_asm int 3;
					//KdPrint(("ZwCreateSection Found!!!\n"));
					//
					//Update information of pwsCrtProcessEvent
					//
					if (pwsCrtProcessEvent == NULL)
					{
						pwsCrtProcessEvent = ExAllocatePoolWithTag(PagedPool, (MAX_PATH + 1) * sizeof (wchar_t), 'CP');
						if (pwsCrtProcessEvent)
						{
							PEPROCESS		pEProcess = PsGetCurrentProcess();
							PSTR			pchParentName = (PSTR)((ULONG_PTR)pEParent + ulProcNameOffset), pchProcessName = (PSTR)((ULONG_PTR)pEProcess + ulProcNameOffset);
							ANSI_STRING		AnsiParentName, AnsiProcessName;
							UNICODE_STRING	uniParentName, uniProcessName;
							ULONG			ulPos = 0;
							
							//_asm int 3;
							
							RtlZeroMemory(pwsCrtProcessEvent, (MAX_PATH + 1) * sizeof (wchar_t));

							RtlInitAnsiString(&AnsiParentName, pchParentName);
							RtlInitAnsiString(&AnsiProcessName, pchProcessName);
							
							RtlAnsiStringToUnicodeString(&uniParentName, &AnsiParentName, TRUE);
							RtlAnsiStringToUnicodeString(&uniProcessName, &AnsiProcessName, TRUE);
							
							RtlStringCchPrintfW(pwsCrtProcessEvent, MAX_PATH, L"%ws;CP;%ws[PID: %ld];TRUE;", uniParentName.Buffer, uniProcessName.Buffer, (ULONG)PsGetCurrentProcessId());
							
							RtlFreeUnicodeString(&uniProcessName);
							RtlFreeUnicodeString(&uniParentName);
							
							if (pKEvtSync[QD_SYNC_EVENTNAME_CRTPROC])
							{
								KeSetEvent(pKEvtSync[QD_SYNC_EVENTNAME_CRTPROC], IO_NO_INCREMENT, FALSE);
							}
							KdPrint(("%S\n", pwsCrtProcessEvent));
						}
					}
					ObDereferenceObject(pEParent);
					ZwTerminateProcess(hProcess, 0);
					ZwClose(hProcess);
					//KdPrint(("ZwCreateSection Found return.\n"));
					return(0);
				}

				ObDereferenceObject(pEParent);
			}
		}
		ZwClose(hProcess);

	}
	
	return(ZwCreateSectionReal(SectionHandle, DesiredAccess, ObjectAttributes, MaximumSize, SectionPageProtection, AllocationAttributes, FileHandle));
}
Esempio n. 11
0
EXTERN_C static NTSTATUS ScvnpScavenge(_Inout_ PFLT_CALLBACK_DATA Data,
                                       _In_ PCFLT_RELATED_OBJECTS FltObjects) {
  PAGED_CODE();

  // Ignore system threads. Thus, this program does not support activities of
  // kernel mode code.
  if (PsIsSystemThread(PsGetCurrentThread())) {
    return STATUS_SUCCESS;
  }

  const auto operationType = FltGetIrpName(Data->Iopb->MajorFunction);

  PFLT_FILE_NAME_INFORMATION fileNameInformation = nullptr;
  auto status = FltGetFileNameInformationUnsafe(
      FltObjects->FileObject, FltObjects->Instance, FLT_FILE_NAME_NORMALIZED,
      &fileNameInformation);
  if (!NT_SUCCESS(status)) {
    // This error is expected to happen and okay to ignore it.
    if (status != STATUS_FILE_DELETED) {
      LOG_ERROR_SAFE("%-25s : FltGetFileNameInformationUnsafe failed (%08x)",
                     operationType, status);
    }
    return status;
  }

  status = FltParseFileNameInformation(fileNameInformation);
  if (!NT_SUCCESS(status)) {
    LOG_ERROR_SAFE("%-25s : FltParseFileNameInformation failed (%08x) for %wZ",
                   operationType, status, &fileNameInformation->Name);
    FltParseFileNameInformation(fileNameInformation);
    return status;
  }

  // Ignore directories
  BOOLEAN isDirectory = FALSE;
  status = FltIsDirectory(FltObjects->FileObject, FltObjects->Instance,
                          &isDirectory);
  if (!NT_SUCCESS(status)) {
    LOG_ERROR_SAFE("%-25s : FltIsDirectory failed (%08x) for %wZ",
                   operationType, status, &fileNameInformation->Name);
    FltParseFileNameInformation(fileNameInformation);
    return status;
  }
  if (isDirectory) {
    FltParseFileNameInformation(fileNameInformation);
    return status;
  }

  // Go through a white list
  if (ScvnpIsWhiteListedFile(&fileNameInformation->Name)) {
    FltParseFileNameInformation(fileNameInformation);
    return status;
  }

  // Get a file size (etc).
  FILE_STANDARD_INFORMATION fileInfo = {};
  status = FltQueryInformationFile(FltObjects->Instance, FltObjects->FileObject,
                                   &fileInfo, sizeof(fileInfo),
                                   FileStandardInformation, nullptr);
  if (!NT_SUCCESS(status)) {
    // This error is expected to happen and okay to ignore it.
    if (status != STATUS_FILE_DELETED) {
      LOG_ERROR_SAFE("%-25s : FltQueryInformationFile failed (%08x) for %wZ",
                     operationType, status, &fileNameInformation->Name);
    }
    FltParseFileNameInformation(fileNameInformation);
    return status;
  }

  // Ignore if the file is empty
  if (fileInfo.EndOfFile.QuadPart == 0) {
    FltParseFileNameInformation(fileNameInformation);
    return status;
  }

  // Ignore if the file size is greater than 4GB
  if (fileInfo.EndOfFile.HighPart != 0) {
    FltParseFileNameInformation(fileNameInformation);
    return STATUS_FILE_TOO_LARGE;
  }

  const auto targetFileSize = fileInfo.EndOfFile.LowPart;

  // Read entire contents of the file onto non paged memory. Thus, it may fail
  // to handle a file larger than the amount of available memory.
  const auto buffer = FltAllocatePoolAlignedWithTag(
      FltObjects->Instance, NonPagedPoolNx, targetFileSize, SCVN_POOL_TAG_NAME);
  if (!buffer) {
    LOG_ERROR_SAFE(
        "%-25s : FltAllocatePoolAlignedWithTag failed (%lu bytes) for %wZ",
        operationType, targetFileSize, &fileNameInformation->Name);
    goto End;
  }
  status = ScvnpReadFile(Data, FltObjects, buffer, targetFileSize);
  if (!NT_SUCCESS(status)) {
    LOG_ERROR_SAFE("%-25s : ScvnpReadFile failed (%08x) for %wZ", operationType,
                   status, &fileNameInformation->Name);
    goto End;
  }

  // Calculate SHA1 of the written data.
  UCHAR sha1Hash[20] = {};
  status = ScvnpGetSha1(sha1Hash, buffer, targetFileSize);
  if (!NT_SUCCESS(status)) {
    LOG_ERROR_SAFE("%-25s : ScvnpGetSha1 failed (%08x) for %wZ", operationType,
                   status, &fileNameInformation->Name);
    goto End;
  }
  wchar_t sha1HashW[41] = {};
  for (auto i = 0; i < RTL_NUMBER_OF(sha1Hash); ++i) {
    const auto outW = sha1HashW + i * 2;
    RtlStringCchPrintfW(outW, 3, L"%02x", sha1Hash[i]);
  }

  // Copy the read file contents to the out put folder as <SHA1>.bin.
  wchar_t outPathW[260];
  status = RtlStringCchPrintfW(outPathW, RTL_NUMBER_OF(outPathW), L"%s\\%s.bin",
                               SCVNP_OUT_DIRECTORY_PATH, sha1HashW);
  if (!NT_SUCCESS(status)) {
    LOG_ERROR_SAFE("%-25s : RtlStringCchPrintfW failed (%08x) for %wZ",
                   operationType, status, &fileNameInformation->Name);
    goto End;
  }
  status =
      ScvnpWriteFile(FltObjects, outPathW, buffer, targetFileSize, FILE_CREATE);
  if (status == STATUS_DELETE_PENDING) {
    status = STATUS_SUCCESS;
    goto End;
  }

  if (status == STATUS_OBJECT_NAME_COLLISION) {
    // The same SHA1 is already there
    LOG_INFO_SAFE("%-25s for %wZ (dup with %S, %lu bytes, %wZ)", operationType,
                  &fileNameInformation->FinalComponent, sha1HashW,
                  targetFileSize, &fileNameInformation->Name);
    status = STATUS_SUCCESS;
    goto End;
  }

  if (!NT_SUCCESS(status)) {
    LOG_ERROR_SAFE("%-25s : ScvnpWriteFile failed (%08x) for %wZ",
                   operationType, status, &fileNameInformation->Name);
    goto End;
  }

  // Done
  LOG_INFO_SAFE("%-25s for %wZ (saved as %S, %lu bytes, %wZ)", operationType,
                &fileNameInformation->FinalComponent, sha1HashW, targetFileSize,
                &fileNameInformation->Name);

End:
  if (buffer) {
    FltFreePoolAlignedWithTag(FltObjects->Instance, buffer, SCVN_POOL_TAG_NAME);
  }
  if (fileNameInformation) {
    FltParseFileNameInformation(fileNameInformation);
  }
  return status;
}
Esempio n. 12
0
static BOOLEAN
CheckForValidPEAndVendor(
    IN HANDLE RootDirectory OPTIONAL,
    IN PCWSTR PathNameToFile,
    OUT PUSHORT Machine,
    OUT PUNICODE_STRING VendorName)
{
    BOOLEAN Success = FALSE;
    NTSTATUS Status;
    HANDLE FileHandle, SectionHandle;
    // SIZE_T ViewSize;
    PVOID ViewBase;
    PIMAGE_NT_HEADERS NtHeader;
    PVOID VersionBuffer = NULL; // Read-only
    PVOID pvData = NULL;
    UINT BufLen = 0;

    if (VendorName->MaximumLength < sizeof(UNICODE_NULL))
        return FALSE;

    *VendorName->Buffer = UNICODE_NULL;
    VendorName->Length = 0;

    Status = OpenAndMapFile(RootDirectory, PathNameToFile,
                            &FileHandle, &SectionHandle, &ViewBase,
                            NULL, FALSE);
    if (!NT_SUCCESS(Status))
    {
        DPRINT1("Failed to open and map file '%S', Status 0x%08lx\n", PathNameToFile, Status);
        return FALSE; // Status;
    }

    /* Make sure it's a valid NT PE file */
    NtHeader = RtlImageNtHeader(ViewBase);
    if (!NtHeader)
    {
        DPRINT1("File '%S' does not seem to be a valid NT PE file, bail out\n", PathNameToFile);
        Status = STATUS_INVALID_IMAGE_FORMAT;
        goto UnmapCloseFile;
    }

    /* Retrieve the target architecture of this PE module */
    *Machine = NtHeader->FileHeader.Machine;

    /*
     * Search for a valid executable version and vendor.
     * NOTE: The module is loaded as a data file, it should be marked as such.
     */
    Status = NtGetVersionResource((PVOID)((ULONG_PTR)ViewBase | 1), &VersionBuffer, NULL);
    if (!NT_SUCCESS(Status))
    {
        DPRINT1("Failed to get version resource for file '%S', Status 0x%08lx\n", PathNameToFile, Status);
        goto UnmapCloseFile;
    }

    Status = NtVerQueryValue(VersionBuffer, L"\\VarFileInfo\\Translation", &pvData, &BufLen);
    if (NT_SUCCESS(Status))
    {
        USHORT wCodePage = 0, wLangID = 0;
        WCHAR FileInfo[MAX_PATH];

        wCodePage = LOWORD(*(ULONG*)pvData);
        wLangID   = HIWORD(*(ULONG*)pvData);

        RtlStringCchPrintfW(FileInfo, ARRAYSIZE(FileInfo),
                            L"StringFileInfo\\%04X%04X\\CompanyName",
                            wCodePage, wLangID);

        Status = NtVerQueryValue(VersionBuffer, FileInfo, &pvData, &BufLen);

        /* Fixup the Status in case pvData is NULL */
        if (NT_SUCCESS(Status) && !pvData)
            Status = STATUS_NOT_FOUND;

        if (NT_SUCCESS(Status) /*&& pvData*/)
        {
            /* BufLen includes the NULL terminator count */
            DPRINT("Found version vendor: \"%S\" for file '%S'\n", pvData, PathNameToFile);

            RtlStringCbCopyNW(VendorName->Buffer, VendorName->MaximumLength,
                              pvData, BufLen * sizeof(WCHAR));
            VendorName->Length = wcslen(VendorName->Buffer) * sizeof(WCHAR);

            Success = TRUE;
        }
    }

    if (!NT_SUCCESS(Status))
        DPRINT("No version vendor found for file '%S'\n", PathNameToFile);

UnmapCloseFile:
    /* Finally, unmap and close the file */
    UnMapAndCloseFile(FileHandle, SectionHandle, ViewBase);

    return Success;
}
Esempio n. 13
0
static VOID
FindNTOSInstallations(
    IN OUT PGENERIC_LIST List,
    IN PPARTLIST PartList,
    IN PPARTENTRY PartEntry)
{
    NTSTATUS Status;
    ULONG DiskNumber = PartEntry->DiskEntry->DiskNumber;
    ULONG PartitionNumber = PartEntry->PartitionNumber;
    HANDLE PartitionDirectoryHandle;
    OBJECT_ATTRIBUTES ObjectAttributes;
    IO_STATUS_BLOCK IoStatusBlock;
    UNICODE_STRING PartitionRootPath;
    BOOT_STORE_TYPE Type;
    PVOID BootStoreHandle;
    ENUM_INSTALLS_DATA Data;
    ULONG Version;
    WCHAR PathBuffer[MAX_PATH];

    ASSERT(PartEntry->IsPartitioned && PartEntry->PartitionNumber != 0);

    /* Set PartitionRootPath */
    RtlStringCchPrintfW(PathBuffer, ARRAYSIZE(PathBuffer),
                        L"\\Device\\Harddisk%lu\\Partition%lu\\",
                        DiskNumber, PartitionNumber);
    RtlInitUnicodeString(&PartitionRootPath, PathBuffer);
    DPRINT("FindNTOSInstallations: PartitionRootPath: '%wZ'\n", &PartitionRootPath);

    /* Open the partition */
    InitializeObjectAttributes(&ObjectAttributes,
                               &PartitionRootPath,
                               OBJ_CASE_INSENSITIVE,
                               NULL,
                               NULL);
    Status = NtOpenFile(&PartitionDirectoryHandle,
                        FILE_LIST_DIRECTORY | FILE_TRAVERSE | SYNCHRONIZE,
                        &ObjectAttributes,
                        &IoStatusBlock,
                        FILE_SHARE_READ | FILE_SHARE_WRITE,
                        FILE_SYNCHRONOUS_IO_NONALERT | FILE_DIRECTORY_FILE);
    if (!NT_SUCCESS(Status))
    {
        DPRINT1("Failed to open partition '%wZ', Status 0x%08lx\n", &PartitionRootPath, Status);
        return;
    }

    Data.List = List;
    Data.PartList = PartList;

    /* Try to see whether we recognize some NT boot loaders */
    for (Type = FreeLdr; Type < BldrTypeMax; ++Type)
    {
        Status = FindBootStore(PartitionDirectoryHandle, Type, &Version);
        if (!NT_SUCCESS(Status))
        {
            /* The loader does not exist, continue with another one */
            DPRINT("Loader type '%d' does not exist, or an error happened (Status 0x%08lx), continue with another one...\n",
                   Type, Status);
            continue;
        }

        /* The loader exists, try to enumerate its boot entries */
        DPRINT("Analyze the OS installations for loader type '%d' in disk #%d, partition #%d\n",
               Type, DiskNumber, PartitionNumber);

        Status = OpenBootStoreByHandle(&BootStoreHandle, PartitionDirectoryHandle, Type, FALSE);
        if (!NT_SUCCESS(Status))
        {
            DPRINT1("Could not open the NTOS boot store of type '%d' (Status 0x%08lx), continue with another one...\n",
                    Type, Status);
            continue;
        }
        EnumerateBootStoreEntries(BootStoreHandle, EnumerateInstallations, &Data);
        CloseBootStore(BootStoreHandle);
    }

    /* Close the partition */
    NtClose(PartitionDirectoryHandle);
}
Esempio n. 14
0
//////////////////////////////////////////////////////////////////////////////////////////////////////////////
//	Description :
//		Registry callback. Logs any registry interaction performed by monitored processes.
//	Parameters :
//		See http://msdn.microsoft.com/en-us/library/windows/hardware/ff560903(v=vs.85).aspx
//	Return value :
//		See http://msdn.microsoft.com/en-us/library/windows/hardware/ff560903(v=vs.85).aspx
//	Process :
//		Checks the operation and logs the associated data.
//////////////////////////////////////////////////////////////////////////////////////////////////////////////
NTSTATUS regCallback (PVOID CallbackContext, PVOID Argument1, PVOID Argument2)
{
	NTSTATUS status, tmpCall;
	UNICODE_STRING full_data, test;
	PUNICODE_STRING tmp = NULL;
	PUNICODE_STRING valueName = NULL;
	PREG_SET_VALUE_KEY_INFORMATION arg = NULL;
	ULONG returnedLength = 0;
	PWCHAR pwBuf = NULL;
	PWCHAR tmp_data = NULL;
	ULONG pid = (ULONG)PsGetCurrentProcessId();
	DWORD i = 0;
	
	if(!isProcessMonitoredByPid(pid) || ExGetPreviousMode() == KernelMode)
		return STATUS_SUCCESS;
	
	pwBuf = ExAllocatePoolWithTag(NonPagedPool, (MAXSIZE+1)*sizeof(WCHAR), BUFFER_TAG);
	if(pwBuf == NULL)
		return STATUS_SUCCESS;
	
	tmp = ExAllocatePoolWithTag(NonPagedPool, MAXSIZE*sizeof(WCHAR), TEMP_TAG);
	if(tmp == NULL)
	{
		ExFreePool(tmp);
		return STATUS_SUCCESS;
	}
	
	switch((REG_NOTIFY_CLASS)Argument1)
	{	
		case RegNtPreDeleteKey:
			status = ObQueryNameString(((PREG_DELETE_KEY_INFORMATION)Argument2)->Object, (POBJECT_NAME_INFORMATION)tmp, MAXSIZE, &returnedLength);
			if(NT_SUCCESS(status))
			{
				#ifdef DEBUG
				DbgPrint("call DeleteKey() \n");
				#endif
				
				if(NT_SUCCESS(RtlStringCchPrintfW(pwBuf, MAXSIZE, L"1,0,s,SubKey->%wZ", tmp)))
					sendLogs(pid, L"REGISTRY_DELETE_KEY", pwBuf);
				else
					sendLogs(pid, L"REGISTRY_DELETE_KEY", L"1,0,s,SubKey->ERROR");
			}
			else
				sendLogs(pid, L"REGISTRY_DELETE_KEY", L"0,-1,s,SubKey->ERROR");
		break;
		
		case RegNtPreSetValueKey: 
			arg = (PREG_SET_VALUE_KEY_INFORMATION)Argument2; 
			status = ObQueryNameString(arg->Object, (POBJECT_NAME_INFORMATION)tmp, MAXSIZE, &returnedLength);
			if(NT_SUCCESS(status))
			{
				#ifdef DEBUG
				DbgPrint("call SetValueKey() \n");
				#endif
				
				switch(arg->Type)
				{
					case REG_SZ:
						tmpCall = RtlStringCchPrintfW(pwBuf, MAXSIZE, L"1,0,sss,SubKey->%wZ,ValueName->%wZ,Data->%ws", tmp, arg->ValueName, ((PWCHAR)arg->Data));
					break;
					default :					
						tmp_data = ExAllocatePoolWithTag(NonPagedPool, MAXSIZE, 'gnaA');
						full_data.MaximumLength = MAXSIZE;
						full_data.Buffer = ExAllocatePoolWithTag(NonPagedPool, full_data.MaximumLength, 'baaH');
						RtlZeroMemory(full_data.Buffer, full_data.MaximumLength);
						for(i=0; i<arg->DataSize; i++)
						{
							if(i==100)
								break;
							RtlStringCchPrintfW(tmp_data, MAXSIZE, L"\\x%02x", *((PWCHAR)arg->Data+i));
							if(i==0)
							{
								RtlInitUnicodeString(&test, tmp_data);
								RtlCopyUnicodeString(&full_data, &test);
							}
							if(NT_SUCCESS(RtlAppendUnicodeToString(&full_data, tmp_data)))
								RtlZeroMemory(tmp_data, MAXSIZE);
						}
						tmpCall = RtlStringCchPrintfW(pwBuf, MAXSIZE, L"1,0,sss,SubKey->%wZ,ValueName->%wZ,Data->%wZ", tmp, arg->ValueName, &full_data);
						ExFreePool(full_data.Buffer);
						ExFreePool(tmp_data);
					break;	
				}
				if(NT_SUCCESS(tmpCall))
					sendLogs(pid, L"REGISTRY_VALUE_KEY_SET", pwBuf);
				else
					sendLogs(pid, L"REGISTRY_VALUE_KEY_SET", L"1,0,sss,SubKey->ERROR,ValueName->ERROR,Data->ERROR");
			}
			else
				sendLogs(pid, L"REGISTRY_VALUE_KEY_SET", L"1,0,sss,SubKey->ERROR,ValueName->ERROR,Data->ERROR");
		break;
		
		case RegNtPreDeleteValueKey:
			status = ObQueryNameString(((PREG_DELETE_VALUE_KEY_INFORMATION)Argument2)->Object, (POBJECT_NAME_INFORMATION)tmp, MAXSIZE, &returnedLength);
			if(NT_SUCCESS(status))
			{
				#ifdef DEBUG
				DbgPrint("call DeleteValueKey() !\n");
				#endif
				if(NT_SUCCESS(RtlStringCchPrintfW(pwBuf, MAXSIZE, L"1,0,ss,SubKey->%wZ,ValueName->%wZ", tmp, ((PREG_DELETE_VALUE_KEY_INFORMATION)Argument2)->ValueName)))
					sendLogs(pid, L"REGISTRY_VALUE_KEY_DELETE", pwBuf);
				else
					sendLogs(pid, L"REGISTRY_VALUE_KEY_DELETE", L"1,0,ss,SubKey->ERROR,ValueName->ERROR");
			}
			else
				sendLogs(pid, L"REGISTRY_VALUE_KEY_DELETE", L"1,0,ss,SubKey->ERROR,ValueName->ERROR");
		break;

		case RegNtPreRenameKey:
			status = ObQueryNameString(((PREG_RENAME_KEY_INFORMATION)Argument2)->Object, (POBJECT_NAME_INFORMATION)tmp, MAXSIZE, &returnedLength);
			if(NT_SUCCESS(status))
			{
				#ifdef DEBUG
				DbgPrint("call RenameKey() !\n");
				#endif
				
				if(NT_SUCCESS(RtlStringCchPrintfW(pwBuf, MAXSIZE, L"1,0,ss,SubKey->%wZ,NewName->%wZ", tmp, ((PREG_RENAME_KEY_INFORMATION)Argument2)->NewName)))
					sendLogs(pid, L"REGISTRY_KEY_RENAME", pwBuf);
				else
					sendLogs(pid, L"REGISTRY_KEY_RENAME", L"1,0,ss,SubKey->ERROR,NewName->ERROR");
			}
			else
				sendLogs(pid, L"REGISTRY_KEY_RENAME", L"1,0,ss,SubKey->ERROR,NewName->ERROR");
		break;
		
		case RegNtPreEnumerateKey:
			status = ObQueryNameString(((PREG_ENUMERATE_KEY_INFORMATION)Argument2)->Object, (POBJECT_NAME_INFORMATION)tmp, MAXSIZE, &returnedLength);
			if(NT_SUCCESS(status))
			{
				#ifdef DEBUG
				DbgPrint("call EnumerateKey() !\n");
				#endif
				
				if(NT_SUCCESS(RtlStringCchPrintfW(pwBuf, MAXSIZE, L"1,0,s,SubKey->%wZ", tmp)))
					sendLogs(pid, L"REGISTRY_ENUMERATE_KEY", pwBuf);
				else
					sendLogs(pid, L"REGISTRY_ENUMERATE_KEY", L"1,0,s,SubKey->ERROR");
			}
			else
				sendLogs(pid, L"REGISTRY_ENUMERATE_KEY", L"1,0,s,SubKey->ERROR");
		break;
		
		case RegNtPreEnumerateValueKey:
			status = ObQueryNameString(((PREG_ENUMERATE_VALUE_KEY_INFORMATION)Argument2)->Object, (POBJECT_NAME_INFORMATION)tmp, MAXSIZE, &returnedLength);
			if(NT_SUCCESS(status))
			{
				#ifdef DEBUG
				DbgPrint("call EnumerateValueKey() !\n");
				#endif
				
				if(NT_SUCCESS(RtlStringCchPrintfW(pwBuf, MAXSIZE, L"1,0,s,SubKey->%wZ", tmp)))
					sendLogs(pid, L"REGISTRY_ENUMERATE_VALUE_KEY", pwBuf);
				else
					sendLogs(pid, L"REGISTRY_ENUMERATE_VALUE_KEY", L"1,0,s,SubKey->ERROR");
			}
			else
				sendLogs(pid, L"REGISTRY_ENUMERATE_VALUE_KEY", L"1,0,s,SubKey->ERROR");
		break;
		
		case RegNtPreQueryKey:
			status = ObQueryNameString(((PREG_QUERY_KEY_INFORMATION)Argument2)->Object, (POBJECT_NAME_INFORMATION)tmp, MAXSIZE, &returnedLength);
			if(NT_SUCCESS(status))
			{
				#ifdef DEBUG
				DbgPrint("call QueryKey()! \n");
				#endif
				if(NT_SUCCESS(RtlStringCchPrintfW(pwBuf, MAXSIZE, L"1,0,s,SubKey->%wZ", tmp)))
					sendLogs(pid, L"REGISTRY_QUERY_KEY", pwBuf);
				else
					sendLogs(pid, L"REGISTRY_QUERY_KEY", L"1,0,s,SubKey->ERROR");
			}
			else
				sendLogs(pid, L"REGISTRY_QUERY_KEY", L"1,0,s,SubKey->ERROR");
		break;
		
		case RegNtPreQueryValueKey:
			status = ObQueryNameString(((PREG_QUERY_VALUE_KEY_INFORMATION)Argument2)->Object, (POBJECT_NAME_INFORMATION)tmp, MAXSIZE, &returnedLength);
			if(NT_SUCCESS(status))
			{
				#ifdef DEBUG
				DbgPrint("call QueryValueKey() !\n");
				#endif
				
				if(NT_SUCCESS(RtlStringCchPrintfW(pwBuf, MAXSIZE, L"1,0,ss,SubKey->%wZ,ValueName->%wZ", tmp, ((PREG_QUERY_VALUE_KEY_INFORMATION)Argument2)->ValueName)))
					sendLogs(pid, L"REGISTRY_QUERY_VALUE_KEY", pwBuf);	
				else
					sendLogs(pid, L"REGISTRY_QUERY_VALUE_KEY", L"1,0,ss,SubKey->ERROR,ValueName->ERROR");
			}
			else
				sendLogs(pid, L"REGISTRY_QUERY_VALUE_KEY", L"1,0,ss,SubKey->ERROR,ValueName->ERROR");
		break;
		
		case RegNtPreCreateKey:
			#ifdef DEBUG
			DbgPrint("call CreateKey() !\n");
			#endif
			if(NT_SUCCESS(RtlStringCchPrintfW(pwBuf, MAXSIZE, L"1,0,s,SubKey->%wZ", ((PREG_PRE_CREATE_KEY_INFORMATION)Argument2)->CompleteName)))
				sendLogs(pid,L"REGISTRY_CREATE_KEY", pwBuf);
			else
				sendLogs(pid, L"REGISTRY_CREATE_KEY", L"1,0,s,SubKey->ERROR");
		break;
		
		case RegNtPreCreateKeyEx:
			#ifdef DEBUG
			DbgPrint("call CreateKeyEx() !\n");
			#endif
			if(NT_SUCCESS(RtlStringCchPrintfW(pwBuf, MAXSIZE, L"1,0,s,SubKey->%wZ", ((PREG_PRE_CREATE_KEY_INFORMATION)Argument2)->CompleteName)))
				sendLogs(pid,L"REGISTRY_CREATE_KEY", pwBuf);
			else
				sendLogs(pid, L"REGISTRY_CREATE_KEY", L"1,0,s,SubKey->ERROR");
		break;
		
		case RegNtPreOpenKey:
			#ifdef DEBUG
			DbgPrint("call OpenKey() !\n");
			#endif
			
			if(((PREG_OPEN_KEY_INFORMATION)Argument2)->CompleteName->Buffer != NULL)
			{
				if(!_wcsicmp(((PREG_OPEN_KEY_INFORMATION)Argument2)->CompleteName->Buffer, L"SOFTWARE\\Oracle\\VirtualBox Guest Additions") || !_wcsicmp(((PREG_OPEN_KEY_INFORMATION)Argument2)->CompleteName->Buffer, L"SOFTWARE\\VMware, Inc.\\VMware Tools"))
				{
					if(NT_SUCCESS(RtlStringCchPrintfW(pwBuf, MAXSIZE, L"0,0,s,SubKey->%wZ", ((PREG_OPEN_KEY_INFORMATION)Argument2)->CompleteName)))
						sendLogs(pid,L"REGISTRY_OPEN_KEY", pwBuf);
					return STATUS_OBJECT_NAME_NOT_FOUND;
				}
				if(NT_SUCCESS(RtlStringCchPrintfW(pwBuf, MAXSIZE, L"1,0,s,SubKey->%wZ", ((PREG_OPEN_KEY_INFORMATION)Argument2)->CompleteName)))
					sendLogs(pid,L"REGISTRY_OPEN_KEY", pwBuf);
				else
					sendLogs(pid, L"REGISTRY_OPEN_KEY", L"1,0,s,SubKey->ERROR");	
			}
			else
				sendLogs(pid, L"REGISTRY_OPEN_KEY", L"1,0,s,SubKey->ERROR");
		break;
		
		case RegNtPreOpenKeyEx:
			#ifdef DEBUG
			DbgPrint("call OpenKeyEx() !\n");
			#endif
			
			if(((PREG_OPEN_KEY_INFORMATION)Argument2)->CompleteName->Buffer != NULL)
			{
				if(!_wcsicmp(((PREG_OPEN_KEY_INFORMATION)Argument2)->CompleteName->Buffer, L"SOFTWARE\\Oracle\\VirtualBox Guest Additions") || !_wcsicmp(((PREG_OPEN_KEY_INFORMATION)Argument2)->CompleteName->Buffer, L"SOFTWARE\\VMware, Inc.\\VMware Tools"))
				{
					if(NT_SUCCESS(RtlStringCchPrintfW(pwBuf, MAXSIZE, L"0,0,s,SubKey->%wZ", ((PREG_OPEN_KEY_INFORMATION)Argument2)->CompleteName)))
						sendLogs(pid,L"REGISTRY_OPEN_KEY", pwBuf);
					return STATUS_OBJECT_NAME_NOT_FOUND;
				}
				if(NT_SUCCESS(RtlStringCchPrintfW(pwBuf, MAXSIZE, L"1,0,s,SubKey->%wZ", ((PREG_OPEN_KEY_INFORMATION)Argument2)->CompleteName)))
					sendLogs(pid,L"REGISTRY_OPEN_KEY", pwBuf);
				else
					sendLogs(pid, L"REGISTRY_OPEN_KEY", L"1,0,s,SubKey->ERROR");	
			}
			else
				sendLogs(pid, L"REGISTRY_OPEN_KEY", L"1,0,s,SubKey->ERROR");
		break;

		default:
		break;
	}
	
	ExFreePool(tmp);
	ExFreePool(pwBuf);
		
	return STATUS_SUCCESS;
 }
Esempio n. 15
0
NTSTATUS Hooked_NtQueryAttributesFile(__in POBJECT_ATTRIBUTES ObjectAttributes,
									  __out PFILE_BASIC_INFORMATION FileInformation)
{
	NTSTATUS statusCall, exceptionCode;
	ULONG currentProcessId;
	UNICODE_STRING kObjectName;
	PWCHAR parameter = NULL; 
	
	PAGED_CODE();
	
	currentProcessId = (ULONG)PsGetCurrentProcessId();
	statusCall = Orig_NtQueryAttributesFile(ObjectAttributes, FileInformation);
	
	if(IsProcessInList(currentProcessId, pMonitoredProcessListHead) && (ExGetPreviousMode() != KernelMode))
	{
		Dbg("Call NtQueryAttributesFile\n");

		parameter = PoolAlloc(MAX_SIZE * sizeof(WCHAR));
		kObjectName.Buffer = NULL;
		
		if(NT_SUCCESS(statusCall))
		{
			__try
			{
				if(ObjectAttributes != NULL)
				{
					ProbeForRead(ObjectAttributes, sizeof(OBJECT_ATTRIBUTES), 1);
					ProbeForRead(ObjectAttributes->ObjectName, sizeof(UNICODE_STRING), 1);
					ProbeForRead(ObjectAttributes->ObjectName->Buffer, ObjectAttributes->ObjectName->Length, 1);
					kObjectName.Length = ObjectAttributes->ObjectName->Length;
					kObjectName.MaximumLength = ObjectAttributes->ObjectName->MaximumLength;
					kObjectName.Buffer = PoolAlloc(kObjectName.MaximumLength);
					RtlCopyUnicodeString(&kObjectName, ObjectAttributes->ObjectName);
				}
				else
					RtlInitUnicodeString(&kObjectName, L"");
			}
			__except(EXCEPTION_EXECUTE_HANDLER)
			{
				exceptionCode = GetExceptionCode();
				if(parameter && NT_SUCCESS(RtlStringCchPrintfW(parameter, MAX_SIZE, L"0,%d,sss,FileHandle->0,buffer->ERROR,offset->0", exceptionCode)))
					SendLogs(currentProcessId, SIG_ntdll_NtQueryAttributesFile, parameter);
				else
					SendLogs(currentProcessId, SIG_ntdll_NtQueryAttributesFile, L"0,-1,sss,FileHandle->0,buffer->ERROR,offset->0");
				if(parameter != NULL)
					PoolFree(parameter);
				return statusCall;
			}			
		
			if(wcsistr(kObjectName.Buffer, L"\\??\\C:\\Windows\\system32\\drivers\\VBoxMouse.sys") || 
				wcsistr(kObjectName.Buffer, L"\\??\\C:\\Windows\\system32\\drivers\\VBoxGuest.sys") ||
				wcsistr(kObjectName.Buffer, L"\\??\\C:\\Windows\\system32\\drivers\\VBoxSF.sys") ||
				wcsistr(kObjectName.Buffer, L"\\??\\C:\\Windows\\system32\\drivers\\VBoxVideo.sys") ||
				wcsistr(kObjectName.Buffer, L"\\??\\C:\\Windows\\system32\\VBoxControl.exe") ||
				wcsistr(kObjectName.Buffer, L"\\??\\C:\\Windows\\system32\\VBoxDisp.dll") ||
				wcsistr(kObjectName.Buffer, L"\\??\\C:\\Windows\\system32\\VBoxHook.dll") ||
				wcsistr(kObjectName.Buffer, L"\\??\\C:\\Windows\\system32\\VBoxMRXNP.dll") ||
				wcsistr(kObjectName.Buffer, L"\\??\\C:\\Windows\\system32\\VBoxOGL.dll") ||
				wcsistr(kObjectName.Buffer, L"\\??\\C:\\Windows\\system32\\VBoxOGLarrayspu.dll") ||
				wcsistr(kObjectName.Buffer, L"\\??\\C:\\Windows\\system32\\VBoxOGLcrutil.dll") ||
				wcsistr(kObjectName.Buffer, L"\\??\\C:\\Windows\\system32\\VBoxOGLerrorspu.dll") ||
				wcsistr(kObjectName.Buffer, L"\\??\\C:\\Windows\\system32\\VBoxOGLfeedbackspu.dll") ||
				wcsistr(kObjectName.Buffer, L"\\??\\C:\\Windows\\system32\\VBoxOGLpackspu.dll") ||
				wcsistr(kObjectName.Buffer, L"\\??\\C:\\Windows\\system32\\VBoxOGLpassthroughspu.dll") ||
				wcsistr(kObjectName.Buffer, L"\\??\\C:\\Windows\\system32\\VBoxService.exe") ||
				wcsistr(kObjectName.Buffer, L"\\??\\C:\\Windows\\system32\\VBoxTray.exe") ||
				wcsistr(kObjectName.Buffer, L"\\??\\C:\\Windows\\system32\\drivers\\vmmouse.sys") ||
				wcsistr(kObjectName.Buffer, L"\\??\\C:\\Windows\\system32\\drivers\\vmhgfs.sys") ||
				wcsistr(kObjectName.Buffer, L"\\??\\C:\\Program Files\\oracle\\virtualbox guest additions\\"))
			{
				if(parameter && NT_SUCCESS(RtlStringCchPrintfW(parameter, MAX_SIZE, L"0,-1,s,filepath->%wZ", &kObjectName)))
					SendLogs(currentProcessId, SIG_ntdll_NtQueryAttributesFile, parameter);
				else
					SendLogs(currentProcessId, SIG_ntdll_NtQueryAttributesFile, L"0,-1,s,filepath->ERROR");
				if(parameter != NULL)
					PoolFree(parameter);
				return INVALID_FILE_ATTRIBUTES;
			}
		}
		if(parameter != NULL)
			PoolFree(parameter);
	}
Esempio n. 16
0
NTSTATUS bus_plugin_dev(ioctl_usbvbus_plugin * plugin, PFDO_DEVICE_DATA  fdodata,
		PFILE_OBJECT fo)
{
    PDEVICE_OBJECT      pdo;
    PPDO_DEVICE_DATA    pdodata, old_pdodata;
    NTSTATUS            status;
    ULONG               len;
    PLIST_ENTRY         entry;
    unsigned long i;

    PAGED_CODE ();

    Bus_KdPrint (fdodata, BUS_DBG_PNP_INFO,
                  ("Exposing PDO\n"
                   "======addr:  %d\n"
                   "======vendor:product: %04x:%04x\n",
                   plugin->addr,
		   plugin->vendor, plugin->product));

    if(plugin->addr <= 0)
        return STATUS_INVALID_PARAMETER;

    ExAcquireFastMutex (&fdodata->Mutex);

    for (entry = fdodata->ListOfPDOs.Flink;
         entry != &fdodata->ListOfPDOs;
         entry = entry->Flink) {

        pdodata = CONTAINING_RECORD (entry, PDO_DEVICE_DATA, Link);
        if (plugin->addr == pdodata->SerialNo &&
            pdodata->DevicePnPState != SurpriseRemovePending)
        {
	    ExReleaseFastMutex (&fdodata->Mutex);
	    return STATUS_INVALID_PARAMETER;
        }
    }

    ExReleaseFastMutex (&fdodata->Mutex);

    // Create the PDO
    //


    Bus_KdPrint(fdodata, BUS_DBG_PNP_NOISE,
                 ("fdodata->NextLowerDriver = 0x%p\n", fdodata->NextLowerDriver));

    //
    // PDO must have a name. You should let the system auto generate a
    // name by specifying FILE_AUTOGENERATED_DEVICE_NAME in the
    // DeviceCharacteristics parameter. Let us create a secure deviceobject,
    // in case the child gets installed as a raw device (RawDeviceOK), to prevent
    // an unpriviledged user accessing our device. This function is avaliable
    // in a static WDMSEC.LIB and can be used in Win2k, XP, and Server 2003
    // Just make sure that  the GUID specified here is not a setup class GUID.
    // If you specify a setup class guid, you must make sure that class is
    // installed before enumerating the PDO.
    //

    status = IoCreateDeviceSecure(fdodata->Self->DriverObject,
                sizeof (PDO_DEVICE_DATA),
                NULL,
                FILE_DEVICE_BUS_EXTENDER,
                FILE_AUTOGENERATED_DEVICE_NAME |FILE_DEVICE_SECURE_OPEN,
                FALSE,
                &SDDL_DEVOBJ_SYS_ALL_ADM_ALL, // read wdmsec.h for more info
                (LPCGUID)&GUID_SD_BUSENUM_PDO,
                &pdo);
    if (!NT_SUCCESS (status)) {
        return status;
    }

    pdodata = (PPDO_DEVICE_DATA) pdo->DeviceExtension;

#define HARDWARE_IDS_TPL L"USB\\Vid_%04x&Pid_%04x&Rev_%04xZUSB\\Vid_%04x&Pid_%04xZ"

    len = sizeof(HARDWARE_IDS_TPL);
    pdodata->HardwareIDs =
            ExAllocatePoolWithTag (NonPagedPool, len, BUSENUM_POOL_TAG);
    if (NULL == pdodata->HardwareIDs) {
        IoDeleteDevice(pdo);
        return STATUS_INSUFFICIENT_RESOURCES;
    }
    RtlStringCchPrintfW(pdodata->HardwareIDs, len/sizeof(wchar_t),
		HARDWARE_IDS_TPL,
	        plugin->vendor, plugin->product, plugin->version,
	        plugin->vendor, plugin->product);
    for(i=0;i<sizeof(HARDWARE_IDS_TPL);i++){
	    if('Z'==pdodata->HardwareIDs[i])
		    pdodata->HardwareIDs[i]=0;
    }
#define COMPATIBLE_IDS_TPL L"USB\\Class_%02x&SubClass_%02x&Prot_%02xZUSB\\Class_%02x&SubClass_%02xZUSB\\Class_%02xZ"
#define COMPATIBLE_COMPOSITE_IDS_TPL L"USB\\Class_%02x&SubClass_%02x&Prot_%02xZUSB\\Class_%02x&SubClass_%02xZUSB\\Class_%02xZUSB\\COMPOSITEZ"
    if(plugin->inum>1)
	   len = sizeof(COMPATIBLE_COMPOSITE_IDS_TPL);
    else
	   len = sizeof(COMPATIBLE_IDS_TPL);
    pdodata->compatible_ids =
            ExAllocatePoolWithTag (NonPagedPool, len, BUSENUM_POOL_TAG);
    RtlZeroMemory(pdodata->compatible_ids, len);
    if (NULL == pdodata->compatible_ids) {
	ExFreePool(pdodata->HardwareIDs);
        IoDeleteDevice(pdo);
        return STATUS_INSUFFICIENT_RESOURCES;
    }
    pdodata->compatible_ids_len = len;
    RtlStringCchPrintfW(pdodata->compatible_ids, len/sizeof(wchar_t),
		(plugin->inum>1)?COMPATIBLE_COMPOSITE_IDS_TPL:COMPATIBLE_IDS_TPL,
	        plugin->int0_class, plugin->int0_subclass, plugin->int0_protocol,
		plugin->int0_class, plugin->int0_subclass,
		plugin->int0_class);
    for(i=0;i<len;i++){
	    if('Z'==pdodata->compatible_ids[i])
		    pdodata->compatible_ids[i]=0;
    }
    old_pdodata = (PPDO_DEVICE_DATA) InterlockedCompareExchange(&((LONG)fo->FsContext), (LONG) pdodata, 0);
    if(old_pdodata){
	    KdPrint(("you can't plugin again"));
	    ExFreePool(pdodata->HardwareIDs);
	    ExFreePool(pdodata->compatible_ids);
	   IoDeleteDevice(pdo);
           return STATUS_INVALID_PARAMETER;
    }
    pdodata->SerialNo = plugin->addr;
    pdodata->fo = fo;
    pdodata->devid = plugin->devid;
    pdodata->speed = plugin->speed;
    bus_init_pdo (pdo, fdodata);

    //
    // Device Relation changes if a new pdo is created. So let
    // the PNP system now about that. This forces it to send bunch of pnp
    // queries and cause the function driver to be loaded.
    //

    IoInvalidateDeviceRelations (fdodata->UnderlyingPDO, BusRelations);

    return status;
}
Esempio n. 17
0
VOID
DiskCreateSymbolicLinks(
    IN PDEVICE_OBJECT DeviceObject
    )

/*++

Routine Description:

    This routine will generate a symbolic link for the specified device object
    using the well known form \\Device\HarddiskX\PartitionY, where X and Y is
    always 0 which represents the entire disk object.

    This routine will not try to delete any previous symbolic link for the
    same generated name - the caller must make sure the symbolic link has
    been broken before calling this routine.

Arguments:

    DeviceObject - the device object to make a well known name for

Return Value:

    STATUS

--*/

{
    PCOMMON_DEVICE_EXTENSION commonExtension = DeviceObject->DeviceExtension;
    PDISK_DATA diskData = commonExtension->DriverData;

    WCHAR wideSourceName[64] = { 0 };
    UNICODE_STRING unicodeSourceName;

    NTSTATUS status;

    PAGED_CODE();

    //
    // Build the destination for the link first using the device name
    // stored in the device object
    //

    NT_ASSERT(commonExtension->DeviceName.Buffer);

    if(!diskData->LinkStatus.WellKnownNameCreated) {
        //
        // Put together the source name using the partition and device number
        // in the device extension and disk data segment
        //

        status = RtlStringCchPrintfW(wideSourceName, sizeof(wideSourceName) / sizeof(wideSourceName[0]) - 1,
                                     L"\\Device\\Harddisk%d\\Partition0",
                                     commonExtension->PartitionZeroExtension->DeviceNumber);

        if (NT_SUCCESS(status)) {

            RtlInitUnicodeString(&unicodeSourceName, wideSourceName);

            TracePrint((TRACE_LEVEL_INFORMATION, TRACE_FLAG_PNP, "DiskCreateSymbolicLink: Linking %wZ to %wZ\n",
                       &unicodeSourceName,
                       &commonExtension->DeviceName));

            status = IoCreateSymbolicLink(&unicodeSourceName,
                                          &commonExtension->DeviceName);

            if(NT_SUCCESS(status)){
                diskData->LinkStatus.WellKnownNameCreated = TRUE;
            }
        }
    }

    if (!diskData->LinkStatus.PhysicalDriveLinkCreated) {

        //
        // Create a physical drive N link using the device number we saved
        // away during AddDevice.
        //

        status = RtlStringCchPrintfW(wideSourceName, sizeof(wideSourceName) / sizeof(wideSourceName[0]) - 1,
                                     L"\\DosDevices\\PhysicalDrive%d",
                                     commonExtension->PartitionZeroExtension->DeviceNumber);
        if (NT_SUCCESS(status)) {

            RtlInitUnicodeString(&unicodeSourceName, wideSourceName);

            TracePrint((TRACE_LEVEL_INFORMATION, TRACE_FLAG_PNP, "DiskCreateSymbolicLink: Linking %wZ to %wZ\n",
                        &unicodeSourceName,
                        &(commonExtension->DeviceName)));

            status = IoCreateSymbolicLink(&unicodeSourceName,
                                          &(commonExtension->DeviceName));

            if(NT_SUCCESS(status)) {
                diskData->LinkStatus.PhysicalDriveLinkCreated = TRUE;
            }
        }
    }
    return;
}
Esempio n. 18
0
/**
* 写日志函数
* @param iLevel:ULONG,要写入日志信息的等级,请参考LogConst.h文件内等级。
* @param format:NTSTRSAFE_PSTR*,输入信息的格式,此格式参考printf。
* @param ...:变参,参考printf,要写入的信息。
* 写日志信息接口,写日志信息大小请不要超过规定长度的大小!最大暂时为256字节!!
*/
void _cdecl WriteSysLog(ULONG iLevel, NTSTRSAFE_PWSTR format,...)
{
	//判断记录日志级别
	if(iLevel > g_logLevel)
		return;

	//获得互斥体,在下面的调用中,所有的函数退出部分都要进行释放互斥体
	KeWaitForSingleObject(&g_logMutex, Executive, KernelMode, FALSE, NULL);
	
	HANDLE logfile;
	OBJECT_ATTRIBUTES   objectAttributes;
	IO_STATUS_BLOCK		ioStatus;
	NTSTATUS ntStatus;
	
	InitializeObjectAttributes(&objectAttributes,&g_logFileName,OBJ_CASE_INSENSITIVE,NULL, NULL);

	
	ntStatus = ZwCreateFile(&logfile,FILE_READ_ATTRIBUTES | FILE_APPEND_DATA | SYNCHRONIZE,
				&objectAttributes,&ioStatus,NULL,FILE_ATTRIBUTE_NORMAL,
				FILE_SHARE_READ|FILE_SHARE_WRITE,FILE_OPEN_IF,FILE_SYNCHRONOUS_IO_NONALERT,NULL,0);
	if(!NT_SUCCESS(ntStatus) )
	{
		KeReleaseMutex(&g_logMutex,FALSE);
		KdPrint( ("Strategy:%d:Init Open file error!\n",g_logStrategy) );
		return;
	}

	//判断文件大小处理的函数
	if(g_logWriteTime >= CHECK_TIME)
	{
		if(g_logStrategy == 1)
		{
			ntStatus = CheckLogFileSizeAndReCreateLogFile(&g_logFileName,1,logfile);

			if(!NT_SUCCESS(ntStatus) )
			{
				KeReleaseMutex(&g_logMutex,FALSE);
				KdPrint( ("Strategy:%d:Init Open file error!\n",g_logStrategy) );
				return;
			}
		}

		g_logWriteTime = 0;
	}

	TIME_FIELDS ctime;
	ctime = GetLocalTime();
	ULONG pid = (ULONG)PsGetCurrentProcessId();
	PWCHAR ptype;

	switch(iLevel)
	{
		case LOG_TYPE_ERROR:	ptype = L"ERROR";break;
		case LOG_TYPE_WARN:		ptype = L"WARNING";break;
		case LOG_TYPE_INFO:		ptype = L"INFO";break;
		default:				ptype = L"DEBUG";break;
	}
    WCHAR strTemp[MAX_INFO_LENGTH];
    RtlZeroMemory(strTemp, MAX_INFO_LENGTH);
    NTSTRSAFE_PWSTR pinfo = strTemp;

 	va_list args; 
    va_start(args,format); 
	ntStatus =::RtlStringCchVPrintfW(pinfo,MAX_INFO_LENGTH*sizeof(WCHAR),format,args);
	if( !NT_SUCCESS(ntStatus) )
	{
		DbgPrint( ("Log info conversion error1!\n") );
		ZwClose(logfile);
		KeReleaseMutex(&g_logMutex,FALSE);
		//在函数所有的出口释放互斥体
		return;
	}
    va_end(args); 

	WCHAR cinfo[MAX_INFO_LENGTH*2];
	RtlZeroMemory(cinfo,MAX_INFO_LENGTH*2*sizeof(WCHAR));//清0,为了下面的操作顺利
	ntStatus = RtlStringCchPrintfW(cinfo,MAX_INFO_LENGTH*2*sizeof(WCHAR), L"%04d-%02d-%02d %02d:%02d:%02d.%03d\t%d\t%s\t%s\r\n", ctime.Year, ctime.Month, ctime.Day, 
		ctime.Hour, ctime.Minute, ctime.Second, ctime.Milliseconds,pid,ptype,pinfo);
	if( !NT_SUCCESS(ntStatus) )
	{
		DbgPrint( ("Log info conversion error2!\n") );
		//在函数所有的出口释放互斥体
		ZwClose(logfile);
		KeReleaseMutex(&g_logMutex,FALSE);
		return;
	}

	size_t length;
	ntStatus = RtlStringCchLengthW(cinfo,MAX_INFO_LENGTH*2,&length);
	if( !NT_SUCCESS(ntStatus) )
	{
		DbgPrint( ("Log info conversion error3!\n") );
		//在函数所有的出口释放互斥体
		ZwClose(logfile);
		KeReleaseMutex(&g_logMutex,FALSE);
		return;
	}
	ntStatus = ZwWriteFile(logfile,NULL,NULL,NULL,&ioStatus,cinfo,length*sizeof(WCHAR),NULL,NULL);
	if( !NT_SUCCESS(ntStatus) )
	{
		DbgPrint( ("Write log error!\n") );
		ZwClose(logfile);
		//在函数所有的出口释放互斥体
		KeReleaseMutex(&g_logMutex,FALSE);
		return;
	}
	g_logWriteTime ++;//增加写入次数

	ZwClose(logfile);
	KeReleaseMutex(&g_logMutex,FALSE);
	//KdPrint( ("write log successful!\n") );
}
BOOLEAN	
XixFsGetScsiportAdapter(
  	IN	PDEVICE_OBJECT				DiskDeviceObject,
  	IN	PDEVICE_OBJECT				*ScsiportAdapterDeviceObject
	) 
{
	SCSI_ADDRESS		ScsiAddress;
	NTSTATUS			ntStatus;
	UNICODE_STRING		ScsiportAdapterName;
	WCHAR				ScsiportAdapterNameBuffer[32];
	WCHAR				ScsiportAdapterNameTemp[32]	= L"";
    OBJECT_ATTRIBUTES	objectAttributes;
    HANDLE				fileHandle					= NULL;
	IO_STATUS_BLOCK		IoStatus;
	PFILE_OBJECT		ScsiportDeviceFileObject	= NULL;



	ntStatus = XixFsRawDevIoCtrl ( 
					DiskDeviceObject,
					IOCTL_SCSI_GET_ADDRESS,
					NULL,
					0,
					(uint8 *)&ScsiAddress,
					sizeof(SCSI_ADDRESS),
					FALSE,
					NULL
					);

	if(!NT_SUCCESS(ntStatus)) {
		DebugTrace( DEBUG_LEVEL_ERROR,  (DEBUG_TARGET_RESOURCE| DEBUG_TARGET_FCB|DEBUG_TARGET_LOCK),
			("XixFsGetScsiportAdapter: LfsFilterDeviceIoControl() failed.\n"));
		goto error_out;

	}

    DebugTrace( DEBUG_LEVEL_ALL,  (DEBUG_TARGET_RESOURCE| DEBUG_TARGET_FCB|DEBUG_TARGET_LOCK),
		("XixFsGetScsiportAdapter: ScsiAddress=Len:%d PortNumber:%d PathId:%d TargetId:%d Lun:%d\n",
						(LONG)ScsiAddress.Length,
						(LONG)ScsiAddress.PortNumber,
						(LONG)ScsiAddress.PathId,
						(LONG)ScsiAddress.TargetId,
						(LONG)ScsiAddress.Lun
						));

	RtlStringCchPrintfW(ScsiportAdapterNameTemp,
						sizeof(ScsiportAdapterNameTemp) / sizeof(ScsiportAdapterNameTemp[0]),
						L"\\Device\\ScsiPort%d",
						ScsiAddress.PortNumber);


	RtlInitEmptyUnicodeString( &ScsiportAdapterName, ScsiportAdapterNameBuffer, sizeof( ScsiportAdapterNameBuffer ) );

    RtlAppendUnicodeToString( &ScsiportAdapterName, ScsiportAdapterNameTemp );

	InitializeObjectAttributes( &objectAttributes,
							&ScsiportAdapterName,
							OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
							NULL,
							NULL);

    //
	// open the file object for the given device
	//
    ntStatus = ZwCreateFile( &fileHandle,
						   SYNCHRONIZE|FILE_READ_DATA,
						   &objectAttributes,
						   &IoStatus,
						   NULL,
						   0,
						   FILE_SHARE_READ | FILE_SHARE_WRITE,
						   FILE_OPEN,
						   FILE_SYNCHRONOUS_IO_NONALERT,
						   NULL,
						   0);
    if (!NT_SUCCESS( ntStatus )) {
	    DebugTrace( DEBUG_LEVEL_ERROR,  (DEBUG_TARGET_RESOURCE| DEBUG_TARGET_FCB),
			("XixFsGetScsiportAdapter: ZwCreateFile() failed.\n"));
		goto error_out;

	}

    ntStatus = ObReferenceObjectByHandle( fileHandle,
										FILE_READ_DATA,
										*IoFileObjectType,
										KernelMode,
										&ScsiportDeviceFileObject,
										NULL);
    if(!NT_SUCCESS( ntStatus )) {

		DebugTrace( DEBUG_LEVEL_ERROR,  (DEBUG_TARGET_RESOURCE| DEBUG_TARGET_FCB|DEBUG_TARGET_LOCK),
			("XixFsGetScsiportAdapter: ObReferenceObjectByHandle() failed.\n"));
        goto error_out;
    }

	*ScsiportAdapterDeviceObject = IoGetRelatedDeviceObject(
											ScsiportDeviceFileObject
									    );

	if(*ScsiportAdapterDeviceObject == NULL) {

		DebugTrace( DEBUG_LEVEL_ERROR,  (DEBUG_TARGET_RESOURCE| DEBUG_TARGET_FCB|DEBUG_TARGET_LOCK),
			("XixFsGetScsiportAdapter: IoGetRelatedDeviceObject() failed.\n"));
		ObDereferenceObject(ScsiportDeviceFileObject);
        goto error_out;
	}

	ObDereferenceObject(ScsiportDeviceFileObject);
	ZwClose(fileHandle);
	ObReferenceObject(*ScsiportAdapterDeviceObject);

	return TRUE;

error_out:
	
	*ScsiportAdapterDeviceObject = NULL;
	if(fileHandle)
		ZwClose(fileHandle);

	return FALSE;
}
Esempio n. 20
0
NTSTATUS
FileDiskQueryPnpID(
    __in PNDAS_LOGICALUNIT_EXTENSION LogicalUnitExtension,
    __in BUS_QUERY_ID_TYPE QueryType,
    __in ULONG Index,
    __inout PUNICODE_STRING UnicodeStringId)
{
    static CONST WCHAR* HARDWARE_IDS[] = {
        NDASPORT_ENUMERATOR_GUID_PREFIX L"FileDisk",
        NDASPORT_ENUMERATOR_NAMED_PREFIX L"FileDisk",
        L"GenDisk",
    };
    static CONST WCHAR* COMPATIBLE_IDS[] = { L"gendisk" };
    WCHAR instanceId[20];
    WCHAR* instanceIdList[] = { instanceId };

    NTSTATUS status;
    PFILEDISK_EXTENSION fileDiskExtension;

    CONST WCHAR** idList;
    ULONG idListCount;

    fileDiskExtension = FileDiskGetExtension(LogicalUnitExtension);

    switch (QueryType)
    {
    case BusQueryDeviceID:
        idList = HARDWARE_IDS;
        idListCount = 1;
        break;
    case BusQueryHardwareIDs:
        idList = HARDWARE_IDS;
        idListCount = countof(HARDWARE_IDS);
        break;
    case BusQueryCompatibleIDs:
        idList = COMPATIBLE_IDS;
        idListCount = countof(COMPATIBLE_IDS);
        break;
    case BusQueryInstanceID:
        idList = (const WCHAR**) instanceIdList;
        idListCount = 1;
        status = RtlStringCchPrintfW(
                     instanceId,
                     countof(instanceId),
                     L"%08X",
                     RtlUlongByteSwap(fileDiskExtension->LogicalUnitAddress));
        ASSERT(NT_SUCCESS(status));
        break;
    case 4 /*BusQueryDeviceSerialNumber*/:
    default:
        return STATUS_NOT_SUPPORTED;
    }

    if (Index >= idListCount)
    {
        return STATUS_NO_MORE_ENTRIES;
    }

    status = RtlUnicodeStringCopyString(
                 UnicodeStringId,
                 idList[Index]);

    return status;
}
Esempio n. 21
0
NTSTATUS
Bus_PDO_QueryDeviceText(
    __in PPDO_DEVICE_DATA     DeviceData,
    __in  PIRP   Irp )
/*++

Routine Description:

    The PnP Manager uses this IRP to get a device's
    description or location information. This string
    is displayed in the "found new hardware" pop-up
    window if no INF match is found for the device.
    Bus drivers are also encouraged to return location
    information for their child devices, but this information
    is optional.

Arguments:

    DeviceData - Pointer to the PDO's device extension.
    Irp          - Pointer to the irp.

Return Value:

    NT STATUS

--*/
{
    PWCHAR  buffer;
    USHORT  length;
    PIO_STACK_LOCATION   stack;
    NTSTATUS    status;

    PAGED_CODE ();

    stack = IoGetCurrentIrpStackLocation (Irp);

    switch (stack->Parameters.QueryDeviceText.DeviceTextType) {

    case DeviceTextDescription:

        //
        // Check to see if any filter driver has set any information.
        // If so then remain silent otherwise add your description.
        // This string must be localized to support various languages.
        //

        switch (stack->Parameters.QueryDeviceText.LocaleId) {

        case 0x00000407 : // German
              // Localize the device text.
              // Until we implement let us fallthru to English

        default: // for all other languages, fallthru to English
        case 0x00000409 : // English
            if (!Irp->IoStatus.Information) {
                // 10 for number of digits in the serial number
                length  = (USHORT) \
                (wcslen(VENDORNAME) + 1 + wcslen(MODEL) + 1 + 10) * sizeof(WCHAR);
                buffer = ExAllocatePoolWithTag (PagedPool,
                                            length, BUSENUM_POOL_TAG);
                if (buffer == NULL ) {
                    status = STATUS_INSUFFICIENT_RESOURCES;
                    break;
                }

                RtlStringCchPrintfW(buffer, length/sizeof(WCHAR), L"%ws%ws%02d", VENDORNAME, MODEL,
                                            DeviceData->SerialNo);
                Bus_KdPrint_Cont (DeviceData, BUS_DBG_PNP_TRACE,
                    ("\tDeviceTextDescription :%ws\n", buffer));

                Irp->IoStatus.Information = (ULONG_PTR) buffer;
            }
            status = STATUS_SUCCESS;
            break;
        } // end of LocalID switch
        break;

    case DeviceTextLocationInformation:

        Bus_KdPrint_Cont (DeviceData, BUS_DBG_PNP_TRACE,
            ("\tDeviceTextLocationInformation: Unknown\n"));

    default:
        status = Irp->IoStatus.Status;
        break;
    }

    return status;

}
Esempio n. 22
0
NTSTATUS
Bus_PDO_QueryDeviceId(
    __in PPDO_DEVICE_DATA     DeviceData,
    __in  PIRP   Irp )
/*++

Routine Description:

    Bus drivers must handle BusQueryDeviceID requests for their
    child devices (child PDOs). Bus drivers can handle requests
    BusQueryHardwareIDs, BusQueryCompatibleIDs, and BusQueryInstanceID
    for their child devices.

    When returning more than one ID for hardware IDs or compatible IDs,
    a driver should list the IDs in the order of most specific to most
    general to facilitate choosing the best driver match for the device.

    Bus drivers should be prepared to handle this IRP for a child device
    immediately after the device is enumerated.


Arguments:

    DeviceData - Pointer to the PDO's device extension.
    Irp          - Pointer to the irp.

Return Value:

    NT STATUS

--*/
{
    PIO_STACK_LOCATION      stack;
    PWCHAR                  buffer;
    ULONG                   length;
    NTSTATUS                status = STATUS_SUCCESS;
    ULONG_PTR               result;

    PAGED_CODE ();

    stack = IoGetCurrentIrpStackLocation (Irp);

    switch (stack->Parameters.QueryId.IdType) {

    case BusQueryDeviceID:

        //
        // DeviceID is unique string to identify a device.
        // This can be the same as the hardware ids (which requires a multi
        // sz).
        //

        buffer = DeviceData->HardwareIDs;

        while (*(buffer++)) {
            while (*(buffer++)) {
                ;
            }
        }

        status = RtlULongPtrSub((ULONG_PTR)buffer, (ULONG_PTR)DeviceData->HardwareIDs, &result);
        if (!NT_SUCCESS(status)) {
           break;
        }


        length = (ULONG)result;

        buffer = ExAllocatePoolWithTag (PagedPool, length, BUSENUM_POOL_TAG);

        if (!buffer) {
           status = STATUS_INSUFFICIENT_RESOURCES;
           break;
        }

        RtlCopyMemory (buffer, DeviceData->HardwareIDs, length);
        Irp->IoStatus.Information = (ULONG_PTR) buffer;
        break;

    case BusQueryInstanceID:
        //
        // total length = number (10 digits to be safe (2^32)) + null wide char
        //
        length = 11 * sizeof(WCHAR);

        buffer = ExAllocatePoolWithTag (PagedPool, length, BUSENUM_POOL_TAG);
        if (!buffer) {
           status = STATUS_INSUFFICIENT_RESOURCES;
           break;
        }
        RtlStringCchPrintfW(buffer, length/sizeof(WCHAR), L"%02d", DeviceData->SerialNo);
        Bus_KdPrint_Cont (DeviceData, BUS_DBG_PNP_INFO,
                     ("\tInstanceID: %ws\n", buffer));
        Irp->IoStatus.Information = (ULONG_PTR) buffer;
        break;


    case BusQueryHardwareIDs:

        //
        // A device has at least one hardware id.
        // In a list of hardware IDs (multi_sz string) for a device,
        // DeviceId is the most specific and should be first in the list.
        //

        buffer = DeviceData->HardwareIDs;

        while (*(buffer++)) {
            while (*(buffer++)) {
                ;
            }
        }

        status = RtlULongPtrSub((ULONG_PTR)buffer, (ULONG_PTR)DeviceData->HardwareIDs, &result);
        if (!NT_SUCCESS(status)) {
           break;
        }

        length = (ULONG)result;

        buffer = ExAllocatePoolWithTag (PagedPool, length, BUSENUM_POOL_TAG);
        if (!buffer) {
           status = STATUS_INSUFFICIENT_RESOURCES;
           break;
        }

        RtlCopyMemory (buffer, DeviceData->HardwareIDs, length);
        Irp->IoStatus.Information = (ULONG_PTR) buffer;
        break;


    case BusQueryCompatibleIDs:

        //
        // The generic ids for installation of this pdo.
        //

        length = BUSENUM_COMPATIBLE_IDS_LENGTH;
        buffer = ExAllocatePoolWithTag (PagedPool, length, BUSENUM_POOL_TAG);
        if (!buffer) {
           status = STATUS_INSUFFICIENT_RESOURCES;
           break;
        }
        RtlCopyMemory (buffer, BUSENUM_COMPATIBLE_IDS, length);
        Irp->IoStatus.Information = (ULONG_PTR) buffer;
        break;

    default:

        status = Irp->IoStatus.Status;

    }
    return status;

}
Esempio n. 23
0
void
InitializeMessage(
_Inout_ CLAIMSMAN_MESSAGE *message,
_In_ PUNICODE_STRING sid,
_In_ PUNICODE_STRING name,
_In_ BOOLEAN ReadAccess,
_In_ BOOLEAN WriteAccess,
_In_ BOOLEAN DeleteAccess,
_In_ LONGLONG size,
_In_ LONGLONG modified,
_In_ NTSTATUS status
)
/*
...
*/
{
	PAGED_CODE();

	PT_DBG_PRINT(PTDBG_TRACE_ROUTINES,
		("claimsman!claimsmanInitializeMessage: Entered\n"));

	// SID
	USHORT len = (sid->Length < ((CLAIMSMAN_MESSAGE_SID_SIZE - 1) * sizeof(WCHAR)))
		? sid->Length
		: (CLAIMSMAN_MESSAGE_SID_SIZE - 1)  * sizeof(WCHAR);

	RtlCopyMemory(message->Sid, sid->Buffer, len);
	message->Sid[(len / sizeof(WCHAR)) + (len % sizeof(WCHAR))] = 0;

	// FileName
	len = (name->Length < ((CLAIMSMAN_MESSAGE_FILENAME_SIZE - 1) * sizeof(WCHAR)))
		? name->Length
		: (CLAIMSMAN_MESSAGE_FILENAME_SIZE - 1)  * sizeof(WCHAR);

	RtlCopyMemory(message->FileName, name->Buffer, len);
	message->FileName[(len / sizeof(WCHAR)) + (len % sizeof(WCHAR))] = 0;

	// Access info
	message->ReadAccess = ReadAccess;
	message->WriteAccess = WriteAccess;
	message->DeleteAccess = DeleteAccess;

	// Size
	message->size = size;
	// Last modified
	TIME_FIELDS  tf;
	message->UnixLastModified = modified;
	LONGLONG tstmp = (modified * 10000) + DIFF_TO_UNIX_EPOCH;
	RtlTimeToTimeFields(&tstmp, &tf);
	RtlStringCchPrintfW((NTSTRSAFE_PWSTR)message->LastModified, CLAIMSMAN_MESSAGE_TIMESTAMP_SIZE - 1, L"%04u-%02u-%02uT%02u:%02u:%02u.%03uZ", tf.Year, tf.Month, tf.Day, tf.Hour, tf.Minute, tf.Second, tf.Milliseconds);

	// Iostatus
	message->Status = status;

	// Event timestamp
	LARGE_INTEGER st;
	KeQuerySystemTime(&st);
	// Store as timestamp (Unix epoch + 3 decimals for milliseconds)
	message->UnixTimeStamp = (st.QuadPart - DIFF_TO_UNIX_EPOCH) / 10000;
	//PT_DBG_PRINT(PTDBG_TRACE_ROUTINES,
	//	("claimsman!claimsmanInitializeMessage: message->UnixTimeStamp: %I64u\n", message->UnixTimeStamp));
	// And as ISO-8601...
	RtlTimeToTimeFields(&st, &tf);
	RtlStringCchPrintfW((NTSTRSAFE_PWSTR)message->TimeStamp, CLAIMSMAN_MESSAGE_TIMESTAMP_SIZE - 1, L"%04u-%02u-%02uT%02u:%02u:%02u.%03uZ", tf.Year, tf.Month, tf.Day, tf.Hour, tf.Minute, tf.Second, tf.Milliseconds);
	//PT_DBG_PRINT(PTDBG_TRACE_ROUTINES,
	//	("claimsman!claimsmanInitializeMessage: message->TimeStamp: %ws\n", message->TimeStamp));
}
Esempio n. 24
0
PDEVICE_OBJECT
XenM2BPdoCreate(PXENM2B_FDO_EXTENSION pFdoExt, PCHAR pDeviceName, UCHAR SlotID)
{
    PDEVICE_OBJECT        pDevice;
    PXENM2B_PDO_EXTENSION pPdoExt;
    NTSTATUS              Status;
    size_t                NameLength;
    ANSI_STRING           AnsiName;
    ULONG                 Hash;

    Status = RtlStringCchLengthA(pDeviceName,
                                 XENM2B_PDO_NAME_LENGTH,
                                 &NameLength);
    if ((!NT_SUCCESS(Status))||(NameLength >= XENM2B_PDO_NAME_LENGTH)) {
        TraceError(("%s: Invalid device name, error: 0x%x length: 0x%x\n",
                   __FUNCTION__, Status, NameLength));
        return NULL;
    }
    if (NameLength == 0) {
        TraceError(("%s: Invalid empty device name\n", __FUNCTION__));
        return NULL;
    }

    Status = IoCreateDevice(pFdoExt->pDriver,
                            sizeof(XENM2B_PDO_EXTENSION),
                            NULL,
                            FILE_DEVICE_UNKNOWN,
                            FILE_DEVICE_SECURE_OPEN | FILE_AUTOGENERATED_DEVICE_NAME,
                            FALSE,
                            &pDevice);
    if (!NT_SUCCESS(Status)) {
        TraceError(("%s: Failed to create new PDO, error: 0x%x\n",
                   __FUNCTION__, Status));
        return NULL;
    }

    pPdoExt = (PXENM2B_PDO_EXTENSION)pDevice->DeviceExtension;
    RtlZeroMemory(pPdoExt, sizeof(XENM2B_PDO_EXTENSION));

    pPdoExt->Type = XenM2BPdo;
    pPdoExt->pDevice = pDevice;

    // Convert the name to UNICODE and store as the device TEXT.
    AnsiName.Length = (USHORT)NameLength;
    AnsiName.MaximumLength = NameLength + sizeof(CHAR);
    AnsiName.Buffer = pDeviceName;

    pPdoExt->DeviceName.Length = 0;
    pPdoExt->DeviceName.MaximumLength = XENM2B_PDO_NAME_LENGTH * sizeof(WCHAR);
    pPdoExt->DeviceName.Buffer = pPdoExt->pDeviceNameW;

    Status = RtlAnsiStringToUnicodeString(&pPdoExt->DeviceName, &AnsiName, FALSE);
    if (!NT_SUCCESS(Status)) {
        TraceError(("%s: Failed to convert ANSI device name %s to UNICODE, error: 0x%x\n",
                   __FUNCTION__, pDeviceName, Status));
        IoDeleteDevice(pDevice);
        return NULL;
    }

    // Create a unique instance ID for this device
    RtlHashUnicodeString(&pPdoExt->DeviceName, FALSE, HASH_STRING_ALGORITHM_DEFAULT, &Hash);
    Status = RtlStringCchPrintfW(&pPdoExt->pInstanceIDW[0],
                                 (XENM2B_PDO_NAME_LENGTH - 1),
                                 L"XH%8.8XS%2.2X",
                                 Hash,
                                 SlotID);
    if (!NT_SUCCESS(Status)) {
        TraceError(("%s: Failed to create Instance ID for device %s, error: 0x%x\n",
                   __FUNCTION__, pDeviceName, Status));
        IoDeleteDevice(pDevice);
        return NULL;
    }
    RtlInitUnicodeString(&pPdoExt->InstanceID, pPdoExt->pInstanceIDW);

    TraceDebug(("%s: %p -> Device: %wZ Instance: %wZ\n",
               __FUNCTION__, pDevice, &pPdoExt->DeviceName, &pPdoExt->InstanceID));

    ExInitializeFastMutex(&pPdoExt->DevicePnPState.PnPStateMutex);
    XenM2BSetPnPState(&pPdoExt->DevicePnPState, PnPStatePresent);

    pPdoExt->SystemPowerState = PowerSystemWorking;
    pPdoExt->DevicePowerState = PowerDeviceD3;

    pDevice->Flags &= ~DO_DEVICE_INITIALIZING;

    return pDevice;
}
Esempio n. 25
0
//////////////////////////////////////////////////////////////////////////
//
//	Event log
//
static
VOID
_WriteLogErrorEntry(
	IN PDEVICE_OBJECT			DeviceObject,
	IN PLSU_ERROR_LOG_ENTRY		LogEntry
){
	PIO_ERROR_LOG_PACKET errorLogEntry;
	WCHAR					strBuff[16];
	NTSTATUS				status;
	ULONG					stringOffset;
	ULONG_PTR				stringLen;
	ULONG					idx_dump;

	//
	//	Parameter to unicode string
	//
	ASSERT(LogEntry->DumpDataEntry <= LSU_MAX_ERRLOG_DATA_ENTRIES);
	ASSERT(KeGetCurrentIrql() == PASSIVE_LEVEL);

	status = RtlStringCchPrintfW(strBuff, 16, L"%u", LogEntry->Parameter2);
	if(!NT_SUCCESS(status)) {
		KDPrint(1, ("RtlStringCchVPrintfW() failed.\n"));
		return;
	}

	status = RtlStringCchLengthW(strBuff, 16, &stringLen);
	if(!NT_SUCCESS(status)) {
		KDPrint(1, ("RtlStringCchLengthW() failed.\n"));
		return;
	}

	//
	//	Translate unicode length into byte length including NULL termination.
	//

	stringLen = ( stringLen + 1 ) * sizeof(WCHAR);
	stringOffset = FIELD_OFFSET(IO_ERROR_LOG_PACKET, DumpData) + LogEntry->DumpDataEntry * sizeof(ULONG);


	errorLogEntry = (PIO_ERROR_LOG_PACKET)
					IoAllocateErrorLogEntry(
									DeviceObject,
									(sizeof(IO_ERROR_LOG_PACKET) +
									(LogEntry->DumpDataEntry * sizeof(ULONG)) +
									(UCHAR)stringLen));
	if(errorLogEntry == NULL) {
		KDPrint(1, ("Could not allocate error log entry.\n"));
		ASSERT(FALSE);
		return ;
	}

	errorLogEntry->ErrorCode = LogEntry->ErrorCode;
	errorLogEntry->MajorFunctionCode = LogEntry->MajorFunctionCode;
	errorLogEntry->IoControlCode = LogEntry->IoctlCode;
	errorLogEntry->EventCategory;
	errorLogEntry->SequenceNumber = LogEntry->SequenceNumber;
	errorLogEntry->RetryCount = (UCHAR) LogEntry->ErrorLogRetryCount;
	errorLogEntry->UniqueErrorValue = LogEntry->UniqueId;
	errorLogEntry->FinalStatus = STATUS_SUCCESS;
	errorLogEntry->DumpDataSize = LogEntry->DumpDataEntry * sizeof(ULONG);
	for(idx_dump=0; idx_dump < LogEntry->DumpDataEntry; idx_dump++) {
		errorLogEntry->DumpData[idx_dump] = LogEntry->DumpData[idx_dump];
	}

	errorLogEntry->NumberOfStrings = 1;
	errorLogEntry->StringOffset = (USHORT)stringOffset;
	RtlCopyMemory((PUCHAR)errorLogEntry + stringOffset, strBuff, stringLen);

	IoWriteErrorLogEntry(errorLogEntry);

	return;
}
Esempio n. 26
0
void
AFSDumpTraceFiles()
{

    NTSTATUS ntStatus = STATUS_SUCCESS;
    HANDLE hDirectory = NULL;
    OBJECT_ATTRIBUTES   stObjectAttribs;
    IO_STATUS_BLOCK stIoStatus;
    LARGE_INTEGER liTime, liLocalTime;
    TIME_FIELDS timeFields;
    ULONG ulBytesWritten = 0;
    HANDLE hDumpFile = NULL;
    ULONG ulBytesProcessed, ulCopyLength;
    LARGE_INTEGER liOffset;
    ULONG ulDumpLength = 0;
    BOOLEAN bSetEvent = FALSE;

    __Enter
    {

        AFSAcquireShared( &AFSDbgLogLock,
                          TRUE);

        ulDumpLength = AFSDbgBufferLength - AFSDbgLogRemainingLength;

        AFSReleaseResource( &AFSDbgLogLock);

        if( AFSDumpFileLocation.Length == 0 ||
            AFSDumpFileLocation.Buffer == NULL ||
            AFSDbgBufferLength == 0 ||
            ulDumpLength == 0 ||
            AFSDumpFileName.MaximumLength == 0 ||
            AFSDumpFileName.Buffer == NULL ||
            AFSDumpBuffer == NULL)
        {
            try_return( ntStatus);
        }

        //
        // Go open the cache file
        //

        InitializeObjectAttributes( &stObjectAttribs,
                                    &AFSDumpFileLocation,
                                    OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE,
                                    NULL,
                                    NULL);

        ntStatus = ZwCreateFile( &hDirectory,
                                 GENERIC_READ | GENERIC_WRITE,
                                 &stObjectAttribs,
                                 &stIoStatus,
                                 NULL,
                                 0,
                                 FILE_SHARE_READ | FILE_SHARE_WRITE,
                                 FILE_OPEN,
                                 FILE_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT,
                                 NULL,
                                 0);

        if( !NT_SUCCESS( ntStatus))
        {

            try_return( ntStatus);
        }

        ntStatus = KeWaitForSingleObject( &AFSDumpFileEvent,
                                          Executive,
                                          KernelMode,
                                          FALSE,
                                          NULL);

        if( !NT_SUCCESS( ntStatus))
        {

            try_return( ntStatus);
        }

        bSetEvent = TRUE;

        AFSDumpFileName.Length = 0;

        RtlZeroMemory( AFSDumpFileName.Buffer,
                       AFSDumpFileName.MaximumLength);

        KeQuerySystemTime( &liTime);

        ExSystemTimeToLocalTime( &liTime,
                                 &liLocalTime);

        RtlTimeToTimeFields( &liLocalTime,
                             &timeFields);

        ntStatus = RtlStringCchPrintfW( AFSDumpFileName.Buffer,
                                        AFSDumpFileName.MaximumLength/sizeof( WCHAR),
                                        L"AFSDumpFile %d.%d.%d %d.%d.%d.log",
                                                  timeFields.Month,
                                                  timeFields.Day,
                                                  timeFields.Year,
                                                  timeFields.Hour,
                                                  timeFields.Minute,
                                                  timeFields.Second);

        if( !NT_SUCCESS( ntStatus))
        {
            try_return( ntStatus);
        }

        RtlStringCbLengthW( AFSDumpFileName.Buffer,
                            AFSDumpFileName.MaximumLength,
                            (size_t *)&ulBytesWritten);

        AFSDumpFileName.Length = (USHORT)ulBytesWritten;

        InitializeObjectAttributes( &stObjectAttribs,
                                    &AFSDumpFileName,
                                    OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE,
                                    hDirectory,
                                    NULL);

        ntStatus = ZwCreateFile( &hDumpFile,
                                 GENERIC_READ | GENERIC_WRITE,
                                 &stObjectAttribs,
                                 &stIoStatus,
                                 NULL,
                                 0,
                                 FILE_SHARE_READ | FILE_SHARE_WRITE,
                                 FILE_CREATE,
                                 FILE_SYNCHRONOUS_IO_NONALERT,
                                 NULL,
                                 0);

        if( !NT_SUCCESS( ntStatus))
        {
            try_return( ntStatus);
        }

        //
        // Write out the trace buffer
        //

        liOffset.QuadPart = 0;

        ulBytesProcessed = 0;

        while( ulBytesProcessed < ulDumpLength)
        {

            ulCopyLength = AFSDumpBufferLength;

            if( ulCopyLength > ulDumpLength - ulBytesProcessed)
            {
                ulCopyLength = ulDumpLength - ulBytesProcessed;
            }

            RtlCopyMemory( AFSDumpBuffer,
                           (void *)((char *)AFSDbgBuffer + ulBytesProcessed),
                           ulCopyLength);

            ntStatus = ZwWriteFile( hDumpFile,
                                    NULL,
                                    NULL,
                                    NULL,
                                    &stIoStatus,
                                    AFSDumpBuffer,
                                    ulCopyLength,
                                    &liOffset,
                                    NULL);

            if( !NT_SUCCESS( ntStatus))
            {
                break;
            }

            liOffset.QuadPart += ulCopyLength;

            ulBytesProcessed += ulCopyLength;
        }

try_exit:

        if( hDumpFile != NULL)
        {
            ZwClose( hDumpFile);
        }

        if( hDirectory != NULL)
        {
            ZwClose( hDirectory);
        }

        if( bSetEvent)
        {
            KeSetEvent( &AFSDumpFileEvent,
                        0,
                        FALSE);
        }
    }

    return;
}
Esempio n. 27
0
BOOL 
ShareMemKImp::InitializeShareMem(HANDLE hFile,
	LPSECURITY_ATTRIBUTES lpAttributes,
	DWORD flProtect,
	DWORD dwMaximumSize,
	LPCWSTR lpName, 
	DWORD dwDesiredAccess,
	ShareMemClassInit* lpInitialization,
	void* lpUserContext) {

	UninitializeShareMem();

	DWORD size;
	size = dwMaximumSize + sizeof(ShareMemHeader);
	if (size < dwMaximumSize)
		return FALSE;

	UNICODE_STRING us;
	RtlInitUnicodeString(&us,
		lpName);

	OBJECT_ATTRIBUTES attr;
	InitializeObjectAttributes(&attr,
		&us,
		OBJ_OPENIF,
		NULL,
		NULL);

	LARGE_INTEGER li;
	li.QuadPart = size;

	NTSTATUS status;
	status = ZwCreateSection(&m_hMapSect,
		READ_CONTROL|WRITE_DAC|dwDesiredAccess,
		&attr,
		&li,
		flProtect,
		SEC_COMMIT,
		hFile);

	BOOLEAN init;
	init = status != STATUS_SUCCESS ? FALSE : TRUE;
	
	if (m_hMapSect) {
		SIZE_T v_size;
		v_size = 0;
		status = ZwMapViewOfSection(m_hMapSect,
			ZwCurrentProcess(),
			&m_hMapView,
			0,
			size,
			NULL,
			&v_size,			
			ViewUnmap,
			0,
			PAGE_READWRITE);
		if (m_hMapView) {
			m_hMapSize = dwMaximumSize;

			ShareMemHeader* smh;
			smh = (ShareMemHeader*)m_hMapView;			
			if (init) {
				LARGE_INTEGER tick;
				KeQueryTickCount(&tick);

				RtlStringCchPrintfW(smh->m_LockName, 
					sizeof(smh->m_LockName), 
					L"K-%08x-%08x-%08x",
					PsGetCurrentProcessId(),
					PsGetCurrentThreadId(),
					tick.LowPart);
								
				if (lpInitialization)
					smh->m_bResult = lpInitialization(this,
						lpUserContext);
				else
					smh->m_bResult = TRUE;

				smh->m_bInitialized = TRUE;
			}
			else
				while(1)
					if (smh->m_bInitialized)
						break;

			return smh->m_bResult;
		}
	}
	return FALSE;
}
Esempio n. 28
0
// for pdo
NTSTATUS DoPdoPnP(PDEVICE_OBJECT pDevice,PIRP pIrp)
{
	NTSTATUS status = STATUS_SUCCESS;
	PPdoExt pPdoExt = static_cast<PPdoExt>(pDevice->DeviceExtension);

	PIO_STACK_LOCATION pIoStack = IoGetCurrentIrpStackLocation(pIrp);

	switch(pIoStack->MinorFunction)
	{
	case IRP_MN_START_DEVICE:
		// set power state
		pPdoExt->m_devPowerState = PowerDeviceD0;
		POWER_STATE state;
		state.DeviceState = PowerDeviceD0;
		PoSetPowerState(pDevice,DevicePowerState,state);

		// set pnp state directly
	case IRP_MN_STOP_DEVICE:
	case IRP_MN_QUERY_STOP_DEVICE:
	case IRP_MN_QUERY_REMOVE_DEVICE:
		SetNewPnpState(pPdoExt,pIoStack->MinorFunction);
		break;

		// check prev state
	case IRP_MN_CANCEL_REMOVE_DEVICE:
		if(pPdoExt->m_ulCurrentPnpState == IRP_MN_QUERY_REMOVE_DEVICE)
		{
			RestorePnpState(pPdoExt);
		}
		break;

		// the same
	case IRP_MN_CANCEL_STOP_DEVICE:
		if(pPdoExt->m_ulCurrentPnpState == IRP_MN_QUERY_STOP_DEVICE)
		{
			RestorePnpState(pPdoExt);
		}
		break;

		// remove
	case IRP_MN_REMOVE_DEVICE:
		{
			// delete only if we have reported the device physical removal
			if(pPdoExt->m_bReportMissing)
			{
				SetNewPnpState(pPdoExt,IRP_MN_REMOVE_DEVICE);

				PDEVICE_OBJECT pFdo = pPdoExt->m_pParentFdo;
				if(pFdo)
				{
					PFdoExt pFdoExt = static_cast<PFdoExt>(pFdo->DeviceExtension);

					// update fdo's pointer
					ExAcquireFastMutex(&pFdoExt->m_mutexEnumPdo);
					pFdoExt->m_pEnumPdo = NULL;
					ExReleaseFastMutex(&pFdoExt->m_mutexEnumPdo);
				}

				// delete device
				IoDeleteDevice(pDevice);
			}

			// if it's present
			if(pPdoExt->m_bPresent)
			{
				// set it as stopped
				SetNewPnpState(pPdoExt,IRP_MN_STOP_DEVICE);
			}
		}
		break;

		// query caps
	case IRP_MN_QUERY_CAPABILITIES:
		{
			PDEVICE_CAPABILITIES pCaps = pIoStack->Parameters.DeviceCapabilities.Capabilities;

			// version check
			if(pCaps->Version != 1 || pCaps->Size < sizeof(DEVICE_CAPABILITIES))
			{
				status = STATUS_UNSUCCESSFUL; 
				break;
			}

			IO_STATUS_BLOCK     ioStatus;
			KEVENT              pnpEvent;
			PDEVICE_OBJECT      pTargetObject;
			PIO_STACK_LOCATION  pIrpStack;
			PIRP                pPnpIrp;

			DEVICE_CAPABILITIES parentCaps;

			RtlZeroMemory(&parentCaps,sizeof(DEVICE_CAPABILITIES));
			parentCaps.Size = sizeof(DEVICE_CAPABILITIES);
			parentCaps.Version = 1;
			parentCaps.Address = -1;
			parentCaps.UINumber = -1;

			KeInitializeEvent(&pnpEvent,NotificationEvent,FALSE);

			pTargetObject = IoGetAttachedDeviceReference(
								static_cast<PFdoExt>(pPdoExt->m_pParentFdo->DeviceExtension)->m_pLowerDevice);

			// get parent fdo's caps
			pPnpIrp = IoBuildSynchronousFsdRequest(IRP_MJ_PNP,pTargetObject,NULL,0,NULL,&pnpEvent,&ioStatus);
			if(pPnpIrp == NULL) 
			{
				status = STATUS_INSUFFICIENT_RESOURCES;
			}
			else
			{
				pPnpIrp->IoStatus.Status = STATUS_NOT_SUPPORTED;
				pIrpStack = IoGetNextIrpStackLocation(pPnpIrp);

				RtlZeroMemory(pIrpStack,sizeof(IO_STACK_LOCATION));
				pIrpStack->MajorFunction = IRP_MJ_PNP;
				pIrpStack->MinorFunction = IRP_MN_QUERY_CAPABILITIES;
				pIrpStack->Parameters.DeviceCapabilities.Capabilities = pCaps;
				status = IoCallDriver(pTargetObject,pPnpIrp);
				if (status == STATUS_PENDING) 
				{
					KeWaitForSingleObject(&pnpEvent,Executive,KernelMode,FALSE,NULL);
					status = ioStatus.Status;
				}
			}

			// dec the ref of the fdo's stack upper device
			ObDereferenceObject(pTargetObject);

			// copy the device state
			RtlCopyMemory(pCaps->DeviceState,parentCaps.DeviceState,(PowerSystemShutdown + 1) * sizeof(DEVICE_POWER_STATE));

			// set our own supported device state
			pCaps->DeviceState[PowerSystemWorking] = PowerDeviceD0;

			if(pCaps->DeviceState[PowerSystemSleeping1] != PowerDeviceD0)
				pCaps->DeviceState[PowerSystemSleeping1] = PowerDeviceD3;

			if(pCaps->DeviceState[PowerSystemSleeping2] != PowerDeviceD0)
				pCaps->DeviceState[PowerSystemSleeping2] = PowerDeviceD3;

			if(pCaps->DeviceState[PowerSystemSleeping3] != PowerDeviceD0)
				pCaps->DeviceState[PowerSystemSleeping3] = PowerDeviceD3;

			// donot support d1 and d2
			pCaps->DeviceD1 = pCaps->DeviceD2 = FALSE;

			// no wake
			pCaps->DeviceWake = PowerDeviceUnspecified;
			pCaps->SystemWake = PowerSystemUnspecified;

			pCaps->WakeFromD0 = FALSE;
			pCaps->WakeFromD1 = FALSE;
			pCaps->WakeFromD2 = FALSE;
			pCaps->WakeFromD3 = FALSE;

			// no latency
			pCaps->D1Latency = 0;
			pCaps->D2Latency = 0;
			pCaps->D3Latency = 0;

			// can eject
			pCaps->EjectSupported = TRUE;

			// don't disable
			pCaps->HardwareDisabled = FALSE;

			// can be removed
			pCaps->Removable = TRUE;

			// don't display surprise remove warning dlg
			pCaps->SurpriseRemovalOK = TRUE;

			// no unique id
			pCaps->UniqueID = FALSE;

			// nead user action for install
			pCaps->SilentInstall = FALSE;

			// bus address
			pCaps->Address = 0;

			// ui display number
			pCaps->UINumber = 0;
		}
		break;

		// query pdo id
	case IRP_MN_QUERY_ID:
		{
			switch(pIoStack->Parameters.QueryId.IdType)
			{
			case BusQueryInstanceID:
				{
					PVOID buffer = ExAllocatePoolWithTag(PagedPool,10,'suBT');
					if(!buffer) 
					{
						status = STATUS_INSUFFICIENT_RESOURCES;
						break;
					}

					RtlStringCchPrintfW(static_cast<PWCHAR>(buffer),10,L"%04d",0);
					pIrp->IoStatus.Information = PtrToUlong(buffer);
					devDebugPrint("\tBusQueryInstanceID\n");
				}
				break;

			case BusQueryDeviceID:
				{
					PVOID buffer = ExAllocatePoolWithTag(PagedPool,PDO_DEVICE_ID_LENGTH,'suBT');
					if(!buffer) 
					{
						status = STATUS_INSUFFICIENT_RESOURCES;
						break;
					}
					RtlCopyMemory(buffer,PDO_DEVICE_ID,PDO_DEVICE_ID_LENGTH);
					pIrp->IoStatus.Information = PtrToUlong(buffer);
					devDebugPrint("\tBusQueryDeviceID\n");
				}
				break;

			case BusQueryHardwareIDs:
				{
					PVOID buffer = ExAllocatePoolWithTag(PagedPool,PDO_HARDWARE_IDS_LENGTH,'suBT');
					if(!buffer) 
					{
						status = STATUS_INSUFFICIENT_RESOURCES;
						break;
					}
					RtlCopyMemory(buffer,PDO_HARDWARE_IDS,PDO_HARDWARE_IDS_LENGTH);
					pIrp->IoStatus.Information = PtrToUlong(buffer);
					devDebugPrint("\tBusQueryHardwareIDs\n");
				}
				break;

			case BusQueryCompatibleIDs:
				{
					PVOID buffer = ExAllocatePoolWithTag(PagedPool,PDO_COMPATIBLE_IDS_LENGTH,'suBT');
					if(!buffer) 
					{
						status = STATUS_INSUFFICIENT_RESOURCES;
						break;
					}
					RtlCopyMemory(buffer,PDO_COMPATIBLE_IDS,PDO_COMPATIBLE_IDS_LENGTH);
					pIrp->IoStatus.Information = PtrToUlong(buffer);
					devDebugPrint("\tBusQueryCompatibleIDs\n");
				}
				break;
			}
		}
		break;

		// query text
	case IRP_MN_QUERY_DEVICE_TEXT:
		{
			switch (pIoStack->Parameters.QueryDeviceText.DeviceTextType) 
			{
			case DeviceTextDescription:
				if(!pIrp->IoStatus.Information) 
				{
					PVOID buffer = ExAllocatePoolWithTag (PagedPool,PDO_TEXT_LENGTH,'suBT');
					if(!buffer) 
					{
						status = STATUS_INSUFFICIENT_RESOURCES;
						break;
					}

					RtlStringCchPrintfW(static_cast<PWCHAR>(buffer),PDO_TEXT_LENGTH,L"%ws",PDO_TEXT);
					
					pIrp->IoStatus.Information = PtrToUlong(buffer);
					devDebugPrint("\tDeviceTextDescription\n");
				}
				break;

			default:
				status = pIrp->IoStatus.Status;
				break;
			}
		}
		break;

		// boot resource
	case IRP_MN_QUERY_RESOURCES:
		{
			PCM_RESOURCE_LIST pResList = static_cast<PCM_RESOURCE_LIST>(ExAllocatePoolWithTag(PagedPool,
																			sizeof(CM_RESOURCE_LIST),'suBT'));

			if(pResList)
			{
				// shareed busnumber resource 
				RtlZeroMemory(pResList,sizeof(CM_RESOURCE_LIST));

				pResList->Count = 1;
				pResList->List[0].BusNumber = 0;
				pResList->List[0].InterfaceType = Internal;
				pResList->List[0].PartialResourceList.Count = 1;
				pResList->List[0].PartialResourceList.Revision = 1;
				pResList->List[0].PartialResourceList.Version = 1;
				pResList->List[0].PartialResourceList.PartialDescriptors[0].ShareDisposition = CmResourceShareShared;
				pResList->List[0].PartialResourceList.PartialDescriptors[0].Type = CmResourceTypeBusNumber;
				pResList->List[0].PartialResourceList.PartialDescriptors[0].u.BusNumber.Length = 1;

				pIrp->IoStatus.Information = PtrToUlong(pResList);
			}
			else
			{
				status = STATUS_INSUFFICIENT_RESOURCES;
			}
		}
		break;

		// resource requirements
	case IRP_MN_QUERY_RESOURCE_REQUIREMENTS:
		{
			PIO_RESOURCE_REQUIREMENTS_LIST pList = static_cast<PIO_RESOURCE_REQUIREMENTS_LIST>(
										ExAllocatePoolWithTag(PagedPool,sizeof(IO_RESOURCE_REQUIREMENTS_LIST),'suBT'));

			if(pList)
			{
				RtlZeroMemory(pList,sizeof(IO_RESOURCE_REQUIREMENTS_LIST));

				pList->ListSize = sizeof(IO_RESOURCE_REQUIREMENTS_LIST);
				pList->AlternativeLists = 1;
				pList->InterfaceType = InterfaceTypeUndefined;
				pList->BusNumber = 0;
				pList->List[0].Version = 1;
				pList->List[0].Revision = 1;
				pList->List[0].Count = 1;
				pList->List[0].Descriptors[0].Option = IO_RESOURCE_PREFERRED;
				pList->List[0].Descriptors[0].ShareDisposition = CmResourceShareShared;

				pList->List[0].Descriptors[0].Type = CmResourceTypeBusNumber;
				pList->List[0].Descriptors[0].u.BusNumber.MaxBusNumber = 0x10;
				pList->List[0].Descriptors[0].u.BusNumber.Length = 1;

				pIrp->IoStatus.Information = PtrToUlong(pList);
			}
			else
			{
				status = STATUS_INSUFFICIENT_RESOURCES;
			}
		}
		break;

		// bus info
	case IRP_MN_QUERY_BUS_INFORMATION:
		{
			PPNP_BUS_INFORMATION busInfo;

			busInfo = static_cast<PPNP_BUS_INFORMATION>(ExAllocatePoolWithTag(PagedPool, sizeof(PNP_BUS_INFORMATION),'suBT'));

			if (busInfo == NULL) 
			{
				status = STATUS_INSUFFICIENT_RESOURCES;
				break;
			}

			busInfo->BusTypeGuid = GUID_TIAMO_BUS;

			busInfo->LegacyBusType = Internal;

			busInfo->BusNumber = 0;

			pIrp->IoStatus.Information = PtrToUlong(busInfo);
		}
		break;

		// usage
	case IRP_MN_DEVICE_USAGE_NOTIFICATION:
		status = STATUS_UNSUCCESSFUL;
		break;

	case IRP_MN_EJECT:
		{
			// device physical removed
			pPdoExt->m_bPresent = FALSE;
		}
		break;

	//case IRP_MN_QUERY_INTERFACE:
	//	break;

		// target relations
	case IRP_MN_QUERY_DEVICE_RELATIONS:
		{
			if(pIoStack->Parameters.QueryDeviceRelations.Type != TargetDeviceRelation)
			{
				/*switch(pIoStack->Parameters.QueryDeviceRelations.Type)
				{
				case EjectionRelations:
				devDebugPrint("\tquery EjectionRelations\n");
				break;
				case PowerRelations:
				devDebugPrint("\tquery PowerRelations\n");
				break;
				case RemovalRelations:
				devDebugPrint("\tquery RemovalRelations\n");
				break;
				case BusDeviceRelation:
				devDebugPrint("\tquery BusDeviceRelation\n");
				break;
				case SingleBusRelations:
				devDebugPrint("\tquery SingleBusRelations\n");
				break;
				}*/
				break;
			}

			PDEVICE_RELATIONS pRel = static_cast<PDEVICE_RELATIONS>(ExAllocatePoolWithTag(PagedPool,sizeof(DEVICE_RELATIONS),'suBT'));
			if(!pRel) 
			{
				status = STATUS_INSUFFICIENT_RESOURCES;
				break;
			}

			pRel->Count = 1;
			pRel->Objects[0] = pDevice;
			ObReferenceObject(pDevice);

			status = STATUS_SUCCESS;
			pIrp->IoStatus.Information = PtrToUlong(pRel);
		}
		break;

	default:
		status = pIrp->IoStatus.Status;
		break;
	}

	// pdo should complete the irp
	pIrp->IoStatus.Status = status;
	IoCompleteRequest (pIrp, IO_NO_INCREMENT);

	return status;
}
Esempio n. 29
0
NTSTATUS KBFAttachDevicesEx(IN PDRIVER_OBJECT aDriverObject, IN PUNICODE_STRING aRegistryPath)
{
    UNREFERENCED_PARAMETER(aDriverObject);
    UNREFERENCED_PARAMETER(aRegistryPath);

    NTSTATUS status = STATUS_SUCCESS;

    // 遍历所有键盘设备
    UNICODE_STRING nameString;
    static WCHAR name[32] = {0};
    ULONG index = 0;

    PDEVICE_OBJECT deviceObject = NULL;
    PFILE_OBJECT fileObject = NULL;

    // 第一个设备
    RtlZeroMemory(name, sizeof(WCHAR)*32);
    RtlStringCchPrintfW(name, 32, L"\\Device\\KeyboardClass%d", index);
    RtlInitUnicodeString(&nameString, name);

    // 打开设备对象
    status = IoGetDeviceObjectPointer(&nameString, FILE_ALL_ACCESS, &fileObject, &deviceObject);
    if (NT_SUCCESS(status))
        ObDereferenceObject(fileObject);

    while (deviceObject != NULL)
    {
        PDEVICE_OBJECT pFilterDeviceObject = NULL;
        PDEVICE_OBJECT pLowerDeviceObject = NULL;

        // 创建一个过滤设备
        status = IoCreateDevice(aDriverObject, sizeof(DEVICE_EXTENSION), NULL,
                                deviceObject->DeviceType, deviceObject->Characteristics, FALSE, &pFilterDeviceObject);

        if (!NT_SUCCESS(status))
        {
            KdPrint(("wykbflt.sys : KBFAttachDevices Couldn't create the Filter Device Object %d\n", index));
            break;
        }

        pLowerDeviceObject = IoAttachDeviceToDeviceStack(pFilterDeviceObject, deviceObject);
        if (!pLowerDeviceObject)
        {
            KdPrint(("wykbflt.sys : Couldn't attach to Device Object\n"));
            IoDeleteDevice(pFilterDeviceObject);
            pFilterDeviceObject = NULL;
            break;
        }

        // 设备扩展
        PDEVICE_EXTENSION deviceExtension = (PDEVICE_EXTENSION)pFilterDeviceObject->DeviceExtension;
        KBFInitDeviceExtension(deviceExtension, pFilterDeviceObject, deviceObject, pLowerDeviceObject);

        // 设置过滤操作
        pFilterDeviceObject->DeviceType = pLowerDeviceObject->DeviceType;	// 要过滤的设备类型跟物理设备类型一致
        pFilterDeviceObject->Characteristics = pLowerDeviceObject->Characteristics;
        pFilterDeviceObject->StackSize = pLowerDeviceObject->StackSize + 1;
        pFilterDeviceObject->Flags |= pLowerDeviceObject->Flags & (DO_BUFFERED_IO | DO_DIRECT_IO | DO_POWER_PAGABLE) ;

        ++index;

        RtlZeroMemory(name, sizeof(WCHAR)*32);
        RtlStringCchPrintfW(name, 32, L"\\Device\\KeyboardClass%d", index);
        RtlInitUnicodeString(&nameString, name);

        // 打开设备对象
        status = IoGetDeviceObjectPointer(&nameString, FILE_ALL_ACCESS, &fileObject, &deviceObject);
        if (NT_SUCCESS(status))
            ObDereferenceObject(fileObject);
        else
            break;
    }

    return STATUS_SUCCESS;
}
Esempio n. 30
0
_Must_inspect_result_
NTSTATUS
WDF_LIBRARY_REGISTER_CLIENT(
    __in  PWDF_BIND_INFO        Info,
    __deref_out   PWDF_DRIVER_GLOBALS * WdfDriverGlobals,
    __deref_inout PVOID             * Context
    )
{
    NTSTATUS           status = STATUS_INVALID_PARAMETER;
    PFX_DRIVER_GLOBALS pFxDriverGlobals;
    WCHAR              insertString[EVTLOG_MESSAGE_SIZE];
    ULONG              rawData[RAW_DATA_SIZE];
    PCLIENT_INFO       clientInfo = NULL;

    __Print((LITERAL(WDF_LIBRARY_REGISTER_CLIENT) ": enter\n"));

    clientInfo = (PCLIENT_INFO)*Context;
    *Context = NULL;

    ASSERT(Info->Version.Major == WdfLibraryInfo.Version.Major);

    //
    // NOTE: If the currently loaded  library < drivers minor version fail the load
    // instead of binding to a lower minor version. The reason for that if there
    // is a newer API or new contract change made the driver shouldn't be using older
    // API than it was compiled with.
    //

    if (Info->Version.Minor > WdfLibraryInfo.Version.Minor) {
        status = RtlStringCchPrintfW(insertString,
                                     RTL_NUMBER_OF(insertString),
                                     L"Driver Version: %d.%d Kmdf Lib. Version: %d.%d",
                                     Info->Version.Major,
                                     Info->Version.Minor,
                                     WdfLibraryInfo.Version.Major,
                                     WdfLibraryInfo.Version.Minor);
        if (!NT_SUCCESS(status)) {
            __Print(("ERROR: RtlStringCchPrintfW failed with Status 0x%x\n", status));
            return status;
        }
        rawData[0] = Info->Version.Major;
        rawData[1] = Info->Version.Minor;
        rawData[2] = WdfLibraryInfo.Version.Major;
        rawData[3] = WdfLibraryInfo.Version.Minor;

        LibraryLogEvent(FxLibraryGlobals.DriverObject,
                       WDFVER_MINOR_VERSION_NOT_SUPPORTED,
                       STATUS_OBJECT_TYPE_MISMATCH,
                       insertString,
                       rawData,
                       sizeof(rawData) );
        //
        // this looks like the best status to return
        //
        return STATUS_OBJECT_TYPE_MISMATCH;

    }

    status = FxLibraryCommonRegisterClient(Info,
                                           WdfDriverGlobals,
                                           clientInfo);

    if (NT_SUCCESS(status)) {
        //
        // The context will be a pointer to FX_DRIVER_GLOBALS
        //
        *Context = GetFxDriverGlobals(*WdfDriverGlobals);

        //
        // Set the WDF_BIND_INFO structure pointer in FxDriverGlobals
        //
        pFxDriverGlobals = GetFxDriverGlobals(*WdfDriverGlobals);
        pFxDriverGlobals->WdfBindInfo = Info;
    }

    return status;
}