Example #1
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 #2
0
/*
* SfuQueryEnvironmentVariableOffset
*
* Purpose:
*
* Return offset to the given environment variable.
*
*/
LPWSTR SfuQueryEnvironmentVariableOffset(
	PUNICODE_STRING Value
	)
{
	UNICODE_STRING   str1;
	PWCHAR           EnvironmentBlock, ptr;

	EnvironmentBlock = RtlGetCurrentPeb()->ProcessParameters->Environment;
	ptr = EnvironmentBlock;

	do {
		if (*ptr == 0)
			return 0;

		RtlSecureZeroMemory(&str1, sizeof(str1));
		RtlInitUnicodeString(&str1, ptr);
		if (RtlPrefixUnicodeString(Value, &str1, TRUE))
			break;
		
		ptr += _strlen(ptr) + 1;

	} while (1);

	return (ptr + Value->Length / sizeof(WCHAR));
}
Example #3
0
BOOLEAN
DfsRtlPrefixPath (
    IN PUNICODE_STRING Prefix,
    IN PUNICODE_STRING Test,
    IN BOOLEAN IgnoreCase
) {
    int cchPrefix;

    if (Prefix->Length > Test->Length) {

        return FALSE;

    }

    cchPrefix = Prefix->Length / sizeof (WCHAR);

    if (Prefix->Length < Test->Length &&
            Test->Buffer[cchPrefix] != L'\\') {

        return FALSE;

    }

    return( RtlPrefixUnicodeString( Prefix, Test, IgnoreCase ) );

}
Example #4
0
/*
 * @implemented
 */
BOOLEAN
IsDriveLetter(PUNICODE_STRING SymbolicName)
{
    WCHAR Letter, Colon;

    /* We must have a precise length */
    if (SymbolicName->Length != DosDevices.Length + 2 * sizeof(WCHAR))
    {
        return FALSE;
    }

    /* Must start with the DosDevices prefix */
    if (!RtlPrefixUnicodeString(&DosDevices, SymbolicName, TRUE))
    {
        return FALSE;
    }

    /* Check if letter is correct */
    Letter = SymbolicName->Buffer[DosDevices.Length / sizeof(WCHAR)];
    if ((Letter < L'A' || Letter > L'Z') && Letter != (WCHAR)-1)
    {
        return FALSE;
    }

    /* And finally it must end with a colon */
    Colon = SymbolicName->Buffer[DosDevices.Length / sizeof(WCHAR) + 1];
    if (Colon != L':')
    {
        return FALSE;
    }

    return TRUE;
}
Example #5
0
/***************************************************************************
 *	get_load_order   (internal)
 *
 * Return the loadorder of a module.
 * The system directory and '.dll' extension is stripped from the path.
 */
enum loadorder get_load_order( const WCHAR *app_name, const WCHAR *path )
{
    enum loadorder ret = LO_INVALID;
    HANDLE std_key, app_key = 0;
    WCHAR *module, *basename;
    UNICODE_STRING path_str;
    int len;

    if (!init_done) init_load_order();
    std_key = get_standard_key();
    if (app_name) app_key = get_app_key( app_name );

    TRACE("looking for %s\n", debugstr_w(path));

    /* Strip path information if the module resides in the system directory
     */
    RtlInitUnicodeString( &path_str, path );
    if (RtlPrefixUnicodeString( &system_dir, &path_str, TRUE ))
    {
        const WCHAR *p = path + system_dir.Length / sizeof(WCHAR);
        while (*p == '\\' || *p == '/') p++;
        if (!strchrW( p, '\\' ) && !strchrW( p, '/' )) path = p;
    }

    if (!(len = strlenW(path))) return ret;
    if (!(module = RtlAllocateHeap( GetProcessHeap(), 0, (len + 2) * sizeof(WCHAR) ))) return ret;
    strcpyW( module+1, path );  /* reserve module[0] for the wildcard char */
    basename = (WCHAR *)get_basename( module+1 );

    if (len >= 4) remove_dll_ext( module + 1 + len - 4 );

    /* first explicit module name */
    if ((ret = get_load_order_value( std_key, app_key, module+1 )) != LO_INVALID)
        goto done;

    /* then module basename preceded by '*' */
    basename[-1] = '*';
    if ((ret = get_load_order_value( std_key, app_key, basename-1 )) != LO_INVALID)
        goto done;

    /* then module basename without '*' (only if explicit path) */
    if (basename != module+1 && ((ret = get_load_order_value( std_key, app_key, basename )) != LO_INVALID))
        goto done;

    /* if loading the main exe with an explicit path, try native first */
    if (!app_name && basename != module+1)
    {
        ret = LO_NATIVE_BUILTIN;
        TRACE( "got main exe default %s for %s\n", debugstr_loadorder(ret), debugstr_w(path) );
        goto done;
    }

    /* and last the hard-coded default */
    ret = LO_DEFAULT;
    TRACE( "got hardcoded %s for %s\n", debugstr_loadorder(ret), debugstr_w(path) );

 done:
    RtlFreeHeap( GetProcessHeap(), 0, module );
    return ret;
}
Example #6
0
//
// DRAID need flush before power down. 
// Copied from LsuClientPnPPowerChange
//
NTSTATUS
DraidTdiClientPnPPowerChange(
	IN PUNICODE_STRING	DeviceName,
	IN PNET_PNP_EVENT	PowerEvent,
	IN PTDI_PNP_CONTEXT	Context1,
	IN PTDI_PNP_CONTEXT	Context2
){
	NTSTATUS				status;
	UNICODE_STRING			lpxPrefix;
	NET_DEVICE_POWER_STATE	powerState;

	UNREFERENCED_PARAMETER(Context1);
	UNREFERENCED_PARAMETER(Context2);

	if (DeviceName==NULL) {
		KDPrintM(DBG_OTHER_ERROR, (
			"NO DEVICE NAME SUPPLIED when power event of type %x.\n",
			PowerEvent->NetEvent));
		return STATUS_SUCCESS;
	}

	if(PowerEvent == NULL) {
		return STATUS_SUCCESS;
	}

	if(PowerEvent->Buffer == NULL ||
		PowerEvent->BufferLength == 0) {
		powerState = NetDeviceStateUnspecified;
	} else {
		powerState = *((PNET_DEVICE_POWER_STATE) PowerEvent->Buffer);
	}

	RtlInitUnicodeString(&lpxPrefix, LPX_BOUND_DEVICE_NAME_PREFIX);
	if(	DeviceName == NULL || RtlPrefixUnicodeString(&lpxPrefix, DeviceName, TRUE) == FALSE) {

		KDPrintM(DBG_OTHER_ERROR, (
			"Not LPX binding device.\n"));

		return STATUS_SUCCESS;
	}

	status = STATUS_SUCCESS;
	switch(PowerEvent->NetEvent) {
		case NetEventSetPower:
			KDPrintM(DBG_OTHER_INFO, ("SetPower\n"));
			if(powerState != NetDeviceStateD0) {
				// Flush all RAID instances if exist.
				DraidFlushAll();				
			}
			break;
		default:
			break;
	}

	// Call default power change handler
	return LsuClientPnPPowerChange(DeviceName, PowerEvent, Context1, Context2);
}
Example #7
0
NTSTATUS getFileIdOA(POBJECT_ATTRIBUTES OA, PLARGE_INTEGER result) {
  WCHAR buf[1024];
  NTSTATUS status;  
  HANDLE hfile;
  IO_STATUS_BLOCK iostatus;

  UNICODE_STRING t1, t2, t3, obj;
  int ok=0;

  if (!getFullPath(buf, sizeof(buf), OA)) {
    uwcscpy(buf, OA->ObjectName);
  }
  debugOutput(L"getFileIdOA object=");
  debugOutput(buf);
  debugOutput(L"\n");

  RtlInitUnicodeString(&obj, buf);
  RtlInitUnicodeString(&t1, L"\\device\\harddisk");
  RtlInitUnicodeString(&t2, L"\\??\\");
  RtlInitUnicodeString(&t3, L"\\device\\lanmanredirector");

  if (RtlPrefixUnicodeString(&t1, &obj, TRUE)) ok = 1;
  else if (RtlPrefixUnicodeString(&t2, &obj, TRUE)) {
    if (obj.Length > 5*sizeof(WCHAR) && obj.Buffer[5]==L':') ok=1;
  }
  else if (RtlPrefixUnicodeString(&t3, &obj, TRUE)) {
    ok=1;
  }
  if (!ok) return STATUS_OBJECT_NAME_INVALID;


  status = ZwOpenFile(&hfile,
		      0,
		      OA,
		      &iostatus,
		      0,
		      0);

  if (status == STATUS_SUCCESS) {
    status = getFileIdHandle(hfile, result);
    ZwClose(hfile);
  }
  return status;
}
Example #8
0
/*
XP的
NDIS!_NDIS_MINIPORT_BLOCK

*/
ULONG	IsPhysicalMiniport(PVOID pMiniportBlock)
{

	PNDIS_MINIPORT_BLOCK	pMini	=	(PNDIS_MINIPORT_BLOCK)pMiniportBlock;
	UNICODE_STRING		ustrPrefix	;
	UNICODE_STRING		ustrPrefix2	;
	RtlInitUnicodeString(&ustrPrefix, L"\\??\\PCI");
	RtlInitUnicodeString(&ustrPrefix2, L"\\??\\USB");

	if (RtlPrefixUnicodeString(&ustrPrefix, &pMini->SymbolicLinkName, FALSE))
	{
		return 1;
	}
	if (RtlPrefixUnicodeString(&ustrPrefix2, &pMini->SymbolicLinkName, FALSE))
	{
		return 2;
	}
	return 0;
}
Example #9
0
static PHISTORY_BUFFER
HistoryFindBuffer(PCSRSS_CONSOLE Console, PUNICODE_STRING ExeName)
{
    PLIST_ENTRY Entry = Console->HistoryBuffers.Flink;
    while (Entry != &Console->HistoryBuffers)
    {
        /* For the history APIs, the caller is allowed to give only part of the name */
        PHISTORY_BUFFER Hist = CONTAINING_RECORD(Entry, HISTORY_BUFFER, ListEntry);
        if (RtlPrefixUnicodeString(ExeName, &Hist->ExeName, TRUE))
            return Hist;
        Entry = Entry->Flink;
    }
    return NULL;
}
Example #10
0
BOOLEAN
NdasPortIsLpxAddress(
	__in PTA_ADDRESS Address,
	__in PUNICODE_STRING DeviceName)
{
	static CONST WCHAR LPX_DEVICE_NAME_PREFIX[] = L"\\device\\lpx" L"_";
	UNICODE_STRING lpxDeviceNamePrefixString;
	BOOLEAN isPrefix;

	RtlInitUnicodeString(&lpxDeviceNamePrefixString, LPX_DEVICE_NAME_PREFIX);

	//
	// As LPX strings are all TDI_ADDRESS_TYPE_UNSPEC, there is no way
	// to tell if the address is LPX other than using prefix compare.
	// LPX device names are like "\device\lpx_{GUID}".
	// 

	if (Address->AddressType != TDI_ADDRESS_TYPE_LPX)
	{
		return FALSE;
	}

	isPrefix = RtlPrefixUnicodeString(
		&lpxDeviceNamePrefixString, 
		DeviceName,
		TRUE);

	if (!isPrefix)
	{
		return FALSE;
	}

	if (Address->AddressLength != sizeof(TDI_ADDRESS_LPX))
	{
		ASSERTMSG("TDI_ADDRESS_LPX size is different?", FALSE);
		return FALSE;
	}

	return TRUE;
}
Example #11
0
/*
 * @implemented
 */
NTSTATUS
CreateStringWithGlobal(IN PUNICODE_STRING DosName,
                       OUT PUNICODE_STRING GlobalString)
{
    UNICODE_STRING IntGlobal;

    if (RtlPrefixUnicodeString(&DosDevices, DosName, TRUE))
    {
        /* DOS device - use DOS global */
        IntGlobal.Length = DosName->Length - DosDevices.Length + DosGlobal.Length;
        IntGlobal.MaximumLength = IntGlobal.Length + sizeof(WCHAR);
        IntGlobal.Buffer = AllocatePool(IntGlobal.MaximumLength);
        if (!IntGlobal.Buffer)
        {
            return STATUS_INSUFFICIENT_RESOURCES;
        }

        RtlCopyMemory(IntGlobal.Buffer, DosGlobal.Buffer, DosGlobal.Length);
        RtlCopyMemory(IntGlobal.Buffer + (DosGlobal.Length / sizeof(WCHAR)),
                      DosName->Buffer + (DosDevices.Length / sizeof(WCHAR)),
                      DosName->Length - DosDevices.Length);
        IntGlobal.Buffer[IntGlobal.Length / sizeof(WCHAR)] = UNICODE_NULL;
    }
    else if (RtlPrefixUnicodeString(&Global, DosName, TRUE))
    {
        /* Switch to DOS global */
        IntGlobal.Length = DosName->Length - Global.Length + DosGlobal.Length;
        IntGlobal.MaximumLength = IntGlobal.Length + sizeof(WCHAR);
        IntGlobal.Buffer = AllocatePool(IntGlobal.MaximumLength);
        if (!IntGlobal.Buffer)
        {
            return STATUS_INSUFFICIENT_RESOURCES;
        }

        RtlCopyMemory(IntGlobal.Buffer, DosGlobal.Buffer, DosGlobal.Length);
        RtlCopyMemory(IntGlobal.Buffer + (DosGlobal.Length / sizeof(WCHAR)),
                      DosName->Buffer + (Global.Length / sizeof(WCHAR)),
                      DosName->Length - Global.Length);
        IntGlobal.Buffer[IntGlobal.Length / sizeof(WCHAR)] = UNICODE_NULL;
    }
    else
    {
        /* Simply duplicate string */
        IntGlobal.Length = DosName->Length;
        IntGlobal.MaximumLength = DosName->MaximumLength;
        IntGlobal.Buffer = AllocatePool(IntGlobal.MaximumLength);
        if (!IntGlobal.Buffer)
        {
            return STATUS_INSUFFICIENT_RESOURCES;
        }

        RtlCopyMemory(IntGlobal.Buffer, DosName->Buffer, IntGlobal.MaximumLength);
    }

    /* Return string */
    GlobalString->Length = IntGlobal.Length;
    GlobalString->MaximumLength = IntGlobal.MaximumLength;
    GlobalString->Buffer = IntGlobal.Buffer;

    return STATUS_SUCCESS;
}
Example #12
0
NTSTATUS
LsuClientPnPPowerChange(
	IN PUNICODE_STRING	DeviceName,
	IN PNET_PNP_EVENT	PowerEvent,
	IN PTDI_PNP_CONTEXT	Context1,
	IN PTDI_PNP_CONTEXT	Context2
){
	NTSTATUS				status;
	UNICODE_STRING			lpxPrefix;
	NET_DEVICE_POWER_STATE	powerState;

	UNREFERENCED_PARAMETER(Context1);
	UNREFERENCED_PARAMETER(Context2);

	if (DeviceName==NULL) {
		KDPrintM(DBG_OTHER_ERROR, (
			"NO DEVICE NAME SUPPLIED when power event of type %x.\n",
			PowerEvent->NetEvent));
		return STATUS_SUCCESS;
	}

	if(PowerEvent == NULL) {
		return STATUS_SUCCESS;
	}

	if(PowerEvent->Buffer == NULL ||
		PowerEvent->BufferLength == 0) {

				powerState = NetDeviceStateUnspecified;
	} else {
		powerState = *((PNET_DEVICE_POWER_STATE) PowerEvent->Buffer);
	}

#if DBG
	if(DeviceName->Buffer) {
		KDPrintM(DBG_OTHER_ERROR, ("DeviceName=%ws PowerEvent=%x BufferLen=%u PowerStat=%x\n",
			DeviceName->Buffer,
			PowerEvent->NetEvent,
			PowerEvent->BufferLength,
			powerState));
	} else {
		KDPrintM(DBG_OTHER_ERROR, ("DeviceName=NULL PowerEvent=%x BufferLen=%u PowerStat=%x\n",
			PowerEvent->NetEvent,
			PowerEvent->BufferLength,
			powerState));
	}
#endif
	//
	//	We support LPX for now.
	//	We need to support TCP/IP for the future.
	//

	RtlInitUnicodeString(&lpxPrefix, LPX_BOUND_DEVICE_NAME_PREFIX);
	if(	DeviceName == NULL || RtlPrefixUnicodeString(&lpxPrefix, DeviceName, TRUE) == FALSE) {

		KDPrintM(DBG_OTHER_ERROR, (
			"Not LPX binding device.\n"));

		return STATUS_SUCCESS;
	}

	status = STATUS_SUCCESS;
	switch(PowerEvent->NetEvent) {
		case NetEventSetPower:
			KDPrintM(DBG_OTHER_INFO, ("SetPower\n"));
#if 0
			if(powerState != NetDeviceStateD0) {
				LARGE_INTEGER	interval;
				LONG			loopCnt;
				KIRQL			oldIrql;

				//
				//	Delay power event if Clients' operations are in progress.
				//

				KDPrintM(DBG_OTHER_INFO, ("Start holding power down\n"));

				interval.QuadPart = - NANO100_PER_SEC;
				loopCnt = 0;
				while(TRUE) {

					ACQUIRE_SPIN_LOCK(&TDICLIENT_CONTEXT.TdiPnPSpinLock, &oldIrql);

					//
					//	If 5 seconds passes after last operation, exit.
					//

					if(TDICLIENT_CONTEXT.ClientInProgressIOCount == 0) {
						LARGE_INTEGER	currentTime;

						LsuCurrentTime(&currentTime);
						if(currentTime.QuadPart - TDICLIENT_CONTEXT.LastOperationTime.QuadPart
							> LSTRANS_LPX_POWERDOWN_TIMEOUT) {

							RELEASE_SPIN_LOCK(&TDICLIENT_CONTEXT.TdiPnPSpinLock, oldIrql);

							break;
						}
					}

					RELEASE_SPIN_LOCK(&TDICLIENT_CONTEXT.TdiPnPSpinLock, oldIrql);

					KeDelayExecutionThread(KernelMode, FALSE, &interval);

					loopCnt ++;
					if(loopCnt >= TDIPNPCLIENT_MAX_HOLDING_LOOP) {
						KDPrintM(DBG_OTHER_ERROR, ("Too long holding.\n"));
						break;
					}
					KDPrintM(DBG_OTHER_INFO, ("Loop count:%u\n", loopCnt));
				}


				//
				//	Hold power down by returning PENDING.
				//

				KDPrintM(DBG_OTHER_INFO, ("Finished holding power down\n"));
			}
#endif
		break;
		case NetEventQueryPower:
			KDPrintM(DBG_OTHER_INFO, ("NetEventQueryPower\n"));
		break;
		case NetEventQueryRemoveDevice:
			KDPrintM(DBG_OTHER_INFO, ("NetEventQueryRemoveDevice\n"));
		break;
		case NetEventCancelRemoveDevice:
			KDPrintM(DBG_OTHER_INFO, ("NetEventCancelRemoveDevice\n"));
		break;
		case NetEventReconfigure:
			KDPrintM(DBG_OTHER_INFO, ("NetEventReconfigure\n"));
		break;
		case NetEventBindList:
			KDPrintM(DBG_OTHER_INFO, ("NetEventBindList\n"));
		break;
		case NetEventBindsComplete:
			KDPrintM(DBG_OTHER_INFO, ("NetEventBindsComplete\n"));
		break;
		case NetEventPnPCapabilities:
			KDPrintM(DBG_OTHER_INFO, ("NetEventPnPCapabilities\n"));
		break;
		default:
			KDPrintM(DBG_OTHER_ERROR, ("Unknown PnP code. %x\n", PowerEvent->NetEvent));
	}

	return status;
}
Example #13
0
NTSTATUS
NtGetMachineIdentifierValue(
    IN OUT PULONG Value
    )

/*++

Routine Description:

    Given a unicode value name this routine will go into the registry
    location for the machine identifier information and get the
    value.

Arguments:

    ValueName - the unicode name for the registry value located in the
                identifier location of the registry.
    Value   - a pointer to the ULONG for the result.

Return Value:

    NTSTATUS

    If STATUS_SUCCESSFUL is returned, the location *Value will be
    updated with the DWORD value from the registry.  If any failing
    status is returned, this value is untouched.

--*/

{
    HANDLE Handle;
    NTSTATUS Status;
    ULONG RequestLength;
    ULONG ResultLength;
    UCHAR Buffer[KEY_WORK_AREA];
    UNICODE_STRING KeyName;
    UNICODE_STRING ValueName;
    OBJECT_ATTRIBUTES ObjectAttributes;
    PKEY_VALUE_FULL_INFORMATION KeyValueInformation;

    //
    // Set default as PC/AT
    //

    *Value = MACHINEID_MS_PCAT;

    KeyName.Buffer = REGISTRY_HARDWARE_DESCRIPTION;
    KeyName.Length = sizeof(REGISTRY_HARDWARE_DESCRIPTION) - sizeof(WCHAR);
    KeyName.MaximumLength = sizeof(REGISTRY_HARDWARE_DESCRIPTION);

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

    Status = NtOpenKey(&Handle,
                       KEY_READ,
                       &ObjectAttributes);

    if (!NT_SUCCESS(Status)) {

        return Status;
    }

    ValueName.Buffer = REGISTRY_MACHINE_IDENTIFIER;
    ValueName.Length = sizeof(REGISTRY_MACHINE_IDENTIFIER) - sizeof(WCHAR);
    ValueName.MaximumLength = sizeof(REGISTRY_MACHINE_IDENTIFIER);

    RequestLength = KEY_WORK_AREA;

    KeyValueInformation = (PKEY_VALUE_FULL_INFORMATION)Buffer;

    Status = NtQueryValueKey(Handle,
                             &ValueName,
                             KeyValueFullInformation,
                             KeyValueInformation,
                             RequestLength,
                             &ResultLength);

    ASSERT( Status != STATUS_BUFFER_OVERFLOW );

    NtClose(Handle);

    if (NT_SUCCESS(Status)) {

        if (KeyValueInformation->DataLength != 0) {

            PWCHAR DataPtr;
            UNICODE_STRING DetectedString, TargetString1, TargetString2;

            //
            // Return contents to the caller.
            //

            DataPtr = (PWCHAR)
              ((PUCHAR)KeyValueInformation + KeyValueInformation->DataOffset);

            //
            // Initialize strings.
            //

            RtlInitUnicodeString( &DetectedString, DataPtr );
            RtlInitUnicodeString( &TargetString1, FUJITSU_FMR_NAME );
            RtlInitUnicodeString( &TargetString2, NEC_PC98_NAME );

            //
            // Check the hardware platform
            //

            if (RtlPrefixUnicodeString( &TargetString1 , &DetectedString , TRUE)) {

                //
                // Fujitsu FMR Series.
                //

                *Value = MACHINEID_FUJITSU_FMR;

            } else if (RtlPrefixUnicodeString( &TargetString2 , &DetectedString , TRUE)) {

                //
                // NEC PC-9800 Seriss
                //

                *Value = MACHINEID_NEC_PC98;

            } else {

                //
                // Standard PC/AT comapatibles
                //

                *Value = MACHINEID_MS_PCAT;

            }

        } else {

            //
            // Treat as if no value was found
            //

            Status = STATUS_OBJECT_NAME_NOT_FOUND;
        }

    }

    return Status;
}
Example #14
0
VOID FASTCALL
LineInputKeyDown(PCSRSS_CONSOLE Console, KEY_EVENT_RECORD *KeyEvent)
{
    UINT Pos = Console->LinePos;
    PHISTORY_BUFFER Hist;
    UNICODE_STRING Entry;
    INT HistPos;

    switch (KeyEvent->wVirtualKeyCode)
    {
    case VK_ESCAPE:
        /* Clear entire line */
        LineInputSetPos(Console, 0);
        LineInputEdit(Console, Console->LineSize, 0, NULL);
        return;
    case VK_HOME:
        /* Move to start of line. With ctrl, erase everything left of cursor */
        LineInputSetPos(Console, 0);
        if (KeyEvent->dwControlKeyState & (LEFT_CTRL_PRESSED | RIGHT_CTRL_PRESSED))
            LineInputEdit(Console, Pos, 0, NULL);
        return;
    case VK_END:
        /* Move to end of line. With ctrl, erase everything right of cursor */
        if (KeyEvent->dwControlKeyState & (LEFT_CTRL_PRESSED | RIGHT_CTRL_PRESSED))
            LineInputEdit(Console, Console->LineSize - Pos, 0, NULL);
        else
            LineInputSetPos(Console, Console->LineSize);
        return;
    case VK_LEFT:
        /* Move left. With ctrl, move to beginning of previous word */
        if (KeyEvent->dwControlKeyState & (LEFT_CTRL_PRESSED | RIGHT_CTRL_PRESSED))
        {
            while (Pos > 0 && Console->LineBuffer[Pos - 1] == L' ') Pos--;
            while (Pos > 0 && Console->LineBuffer[Pos - 1] != L' ') Pos--;
        }
        else
        {
            Pos -= (Pos > 0);
        }
        LineInputSetPos(Console, Pos);
        return;
    case VK_RIGHT:
    case VK_F1:
        /* Move right. With ctrl, move to beginning of next word */
        if (KeyEvent->dwControlKeyState & (LEFT_CTRL_PRESSED | RIGHT_CTRL_PRESSED))
        {
            while (Pos < Console->LineSize && Console->LineBuffer[Pos] != L' ') Pos++;
            while (Pos < Console->LineSize && Console->LineBuffer[Pos] == L' ') Pos++;
            LineInputSetPos(Console, Pos);
            return;
        }
        else
        {
            /* Recall one character (but don't overwrite current line) */
            HistoryGetCurrentEntry(Console, &Entry);
            if (Pos < Console->LineSize)
                LineInputSetPos(Console, Pos + 1);
            else if (Pos * sizeof(WCHAR) < Entry.Length)
                LineInputEdit(Console, 0, 1, &Entry.Buffer[Pos]);
        }
        return;
    case VK_INSERT:
        /* Toggle between insert and overstrike */
        Console->LineInsertToggle = !Console->LineInsertToggle;
        ConioSetCursorInfo(Console, Console->ActiveBuffer);
        return;
    case VK_DELETE:
        /* Remove character to right of cursor */
        if (Pos != Console->LineSize)
            LineInputEdit(Console, 1, 0, NULL);
        return;
    case VK_PRIOR:
        /* Recall first history entry */
        LineInputRecallHistory(Console, -((WORD)-1));
        return;
    case VK_NEXT:
        /* Recall last history entry */
        LineInputRecallHistory(Console, +((WORD)-1));
        return;
    case VK_UP:
    case VK_F5:
        /* Recall previous history entry. On first time, actually recall the
         * current (usually last) entry; on subsequent times go back. */
        LineInputRecallHistory(Console, Console->LineUpPressed ? -1 : 0);
        Console->LineUpPressed = TRUE;
        return;
    case VK_DOWN:
        /* Recall next history entry */
        LineInputRecallHistory(Console, +1);
        return;
    case VK_F3:
        /* Recall remainder of current history entry */
        HistoryGetCurrentEntry(Console, &Entry);
        if (Pos * sizeof(WCHAR) < Entry.Length)
        {
            UINT InsertSize = (Entry.Length / sizeof(WCHAR) - Pos);
            UINT DeleteSize = min(Console->LineSize - Pos, InsertSize);
            LineInputEdit(Console, DeleteSize, InsertSize, &Entry.Buffer[Pos]);
        }
        return;
    case VK_F6:
        /* Insert a ^Z character */
        KeyEvent->uChar.UnicodeChar = 26;
        break;
    case VK_F7:
        if (KeyEvent->dwControlKeyState & (LEFT_ALT_PRESSED | RIGHT_ALT_PRESSED))
            HistoryDeleteBuffer(HistoryCurrentBuffer(Console));
        return;
    case VK_F8:
        /* Search for history entries starting with input. */
        if (!(Hist = HistoryCurrentBuffer(Console)) || Hist->NumEntries == 0)
            return;

        /* Like Up/F5, on first time start from current (usually last) entry,
         * but on subsequent times start at previous entry. */
        if (Console->LineUpPressed)
            Hist->Position = (Hist->Position ? Hist->Position : Hist->NumEntries) - 1;
        Console->LineUpPressed = TRUE;

        Entry.Length = Console->LinePos * sizeof(WCHAR);
        Entry.Buffer = Console->LineBuffer;

        /* Keep going backwards, even wrapping around to the end,
         * until we get back to starting point */
        HistPos = Hist->Position;
        do
        {
            if (RtlPrefixUnicodeString(&Entry, &Hist->Entries[HistPos], FALSE))
            {
                Hist->Position = HistPos;
                LineInputEdit(Console, Console->LineSize - Pos,
                              Hist->Entries[HistPos].Length / sizeof(WCHAR) - Pos,
                              &Hist->Entries[HistPos].Buffer[Pos]);
                /* Cursor stays where it was */
                LineInputSetPos(Console, Pos);
                return;
            }
            if (--HistPos < 0) HistPos += Hist->NumEntries;
        } while (HistPos != Hist->Position);
        return;
    }

    if (KeyEvent->uChar.UnicodeChar == L'\b' && Console->Mode & ENABLE_PROCESSED_INPUT)
    {
        /* backspace handling - if processed input enabled then we handle it here
         * otherwise we treat it like a normal char. */
        if (Pos > 0)
        {
            LineInputSetPos(Console, Pos - 1);
            LineInputEdit(Console, 1, 0, NULL);
        }
    }
    else if (KeyEvent->uChar.UnicodeChar == L'\r')
    {
        HistoryAddEntry(Console);

        /* TODO: Expand aliases */

        LineInputSetPos(Console, Console->LineSize);
        Console->LineBuffer[Console->LineSize++] = L'\r';
        if (Console->Mode & ENABLE_ECHO_INPUT)
            ConioWriteConsole(Console, Console->ActiveBuffer, "\r", 1, TRUE);

        /* Add \n if processed input. There should usually be room for it,
         * but an exception to the rule exists: the buffer could have been 
         * pre-filled with LineMaxSize - 1 characters. */
        if (Console->Mode & ENABLE_PROCESSED_INPUT &&
            Console->LineSize < Console->LineMaxSize)
        {
            Console->LineBuffer[Console->LineSize++] = L'\n';
            if (Console->Mode & ENABLE_ECHO_INPUT)
                ConioWriteConsole(Console, Console->ActiveBuffer, "\n", 1, TRUE);
        }
        Console->LineComplete = TRUE;
        Console->LinePos = 0;
    }
    else if (KeyEvent->uChar.UnicodeChar != L'\0')
    {
        if (KeyEvent->uChar.UnicodeChar < 0x20 &&
            Console->LineWakeupMask & (1 << KeyEvent->uChar.UnicodeChar))
        {
            /* Control key client wants to handle itself (e.g. for tab completion) */
            Console->LineBuffer[Console->LineSize++] = L' ';
            Console->LineBuffer[Console->LinePos] = KeyEvent->uChar.UnicodeChar;
            Console->LineComplete = TRUE;
            Console->LinePos = 0;
        }
        else
        {
            /* Normal character */
            BOOL Overstrike = Console->LineInsertToggle && Console->LinePos != Console->LineSize;
            LineInputEdit(Console, Overstrike, 1, &KeyEvent->uChar.UnicodeChar);
        }
    }
}
Example #15
0
VOID
DraidPnpDelAddressHandler( 
	IN PTA_ADDRESS NetworkAddress,
	IN PUNICODE_STRING DeviceName,
	IN PTDI_PNP_CONTEXT Context
    )
/*++

Routine Description:

    TDI delete address handler

Arguments:
    
    NetworkAddress  - network address that is no longer available on the system

    Context1        - name of the device to which address belongs

    Context2        - PDO to which address belongs


Return Value:

    None

--*/
{
	UNICODE_STRING	lpxPrefix;

	PAGED_CODE ();

	UNREFERENCED_PARAMETER(Context);

	if (DeviceName==NULL) {
		KDPrintM(DBG_OTHER_ERROR, (
			"AfdDelAddressHandler: "
			"NO DEVICE NAME SUPPLIED when deleting address of type %d.\n",
			NetworkAddress->AddressType));
		return;
	}

	if (g_DraidGlobals == NULL) {
		ASSERT(FALSE);
		KDPrintM(DBG_OTHER_ERROR, ("DRAID is not active.\n",
			NetworkAddress->AddressType));
		return; 
	}
	
	KDPrintM(DBG_OTHER_TRACE, ("DeviceName=%ws AddrType=%u AddrLen=%u\n",
		DeviceName->Buffer,
		(ULONG)NetworkAddress->AddressType,
		(ULONG)NetworkAddress->AddressLength));

	//
	//	LPX
	//
	RtlInitUnicodeString(&lpxPrefix, LPX_BOUND_DEVICE_NAME_PREFIX);

	if(	RtlPrefixUnicodeString(&lpxPrefix, DeviceName, TRUE)){
		PTDI_ADDRESS_LPX	lpxAddr;

		lpxAddr = (PTDI_ADDRESS_LPX)NetworkAddress->Address;
		KDPrintM(DBG_OTHER_ERROR, ("LPX address deleted: %02x:%02x:%02x:%02x:%02x:%02x\n",
			lpxAddr->Node[0],
			lpxAddr->Node[1],
			lpxAddr->Node[2],
			lpxAddr->Node[3],
			lpxAddr->Node[4],
			lpxAddr->Node[5]));
		RtlZeroMemory(lpxAddr->Reserved, sizeof(lpxAddr->Reserved));		

		DraidListnerDelAddress(lpxAddr);
	} else if(NetworkAddress->AddressType == TDI_ADDRESS_TYPE_IP) {
		//
		//	IP	address
		//

		PTDI_ADDRESS_IP	ipAddr;
		PUCHAR			digit;

		ipAddr = (PTDI_ADDRESS_IP)NetworkAddress->Address;
		digit = (PUCHAR)&ipAddr->in_addr;
		KDPrintM(DBG_OTHER_TRACE, ("IP: %u.%u.%u.%u\n",digit[0],digit[1],digit[2],digit[3]));
	} else {
		KDPrintM(DBG_OTHER_TRACE, ("AddressType %u discarded.\n", (ULONG)NetworkAddress->AddressType));
	}
}
Example #16
0
VOID HandleMediaChangeEvent( UINT uidCdRom )
{
    /*
     * Local variables
     */
    HANDLE                  hDevice;
    ULONG                   id;
    DWORD                   cb;
    DWORD                   dwLogicalDrives;
    DWORD                   dwDriveMask;
    DWORD                   dwDriveCount;
    DWORD                   dwRecipients;
    BOOL                    bResult;
    INT                     nCurrentTry;
    NTSTATUS                Status;
    UNICODE_STRING          ustrCdRom;
    UNICODE_STRING          ustrCdRomId;
    UNICODE_STRING          ustrAnyCdRom;
    UNICODE_STRING          ustrNtPath;
    DEV_BROADCAST_VOLUME    dbcvInfo;
    LPWSTR                  lpszCdRom = TEXT("\\Device\\CdRom");
    WCHAR                   szDrive[] = TEXT("A:\\");
    WCHAR                   szDevice[] = TEXT("\\\\.\\A:");
    WCHAR                   wcDrive;
    WCHAR                   szCdRom[32];
    WCHAR                   szBuff[256];


    UserAssert(uidCdRom >= 0 && uidCdRom < NUM_MEDIA_EVENTS);  // at most 24 cd-rom drives in system


    /*
     * Some initializations
     */
    RtlInitUnicodeString( &ustrAnyCdRom, lpszCdRom );
    wcDrive = UNICODE_NULL;

    /*
     * Form the \Device\CdRomX name based on uidCdRom
     */
    wsprintfW( szCdRom, L"\\Device\\CdRom%d", uidCdRom );
    RtlInitUnicodeString( &ustrCdRom, szCdRom );

    /*
     * The uidCdRom parameter tells us which CD-ROM device generated the
     * MediaChange event.  We need to map this device back to it's logical
     * drive letter because WM_DEVICECHANGE is based on drive letters.
     *
     * To avoid always searching all logical drives, we cache the last
     * associated drive letter.  We still need to check this every time
     * we get notified because WinDisk can remap drive letters.
     */
    if (wcDriveCache[uidCdRom]) {
        /*
         * Convert our DOS path name to a NT path name
         */
        ustrNtPath.MaximumLength = sizeof(szBuff);
        ustrNtPath.Length = 0;
        ustrNtPath.Buffer = szBuff;
        bResult = GetDeviceObject(wcDriveCache[uidCdRom], &ustrNtPath);
        if (bResult) {
            /*
             * Check to see if this drive letter is the one that maps
             * to the CD-ROM drive that just notified us.
             */
            if (RtlEqualUnicodeString(&ustrCdRom, &ustrNtPath, TRUE)) {
                /*
                 * Yes, we found a match
                 */
                wcDrive  = wcDriveCache[uidCdRom];
            }
        }
    }

    if (!wcDrive) {
        /*
         * Either the cache wasn't initialized, or we had a re-mapping
         * of drive letters.  Scan all drive letters looking for CD-ROM
         * devices and update the cache as we go.
         */
        RtlZeroMemory(wcDriveCache, sizeof(wcDriveCache));
        szDrive[0] = L'A';
        szDevice[4] = L'A';
        dwDriveCount = 26; //Max number of drive letters
        dwDriveMask = 1; //Max number of drive letters
        dwLogicalDrives = GetLogicalDrives();

        while (dwDriveCount) {
            /*
             * Is this logical drive a CD-ROM?
             */

//
// JOHNC - Remove after GetDriveType() is fixed
            if ((dwLogicalDrives & dwDriveMask) &&
                GetDriveType(szDrive) == DRIVE_CDROM) {
                /*
                 * For this CD-ROM drive, find it's NT path.
                 */
                ustrNtPath.MaximumLength = sizeof(szBuff);
                ustrNtPath.Length = 0;
                ustrNtPath.Buffer = szBuff;
                bResult = GetDeviceObject(szDrive[0], &ustrNtPath);
                if (bResult) {
                    /*
                     * Make sure the string is in the form \Device\CdRom
                     */
                    if (RtlPrefixUnicodeString(&ustrAnyCdRom, &ustrNtPath, TRUE)) {
                        /*
                         * Now find it's id.  We have a string that looks like
                         * \Device\CdRom??? where ??? is the unit id
                         */
                        RtlInitUnicodeString(&ustrCdRomId,
                                             (PWSTR)((PSTR)(ustrNtPath.Buffer)+ustrAnyCdRom.Length));
                        RtlUnicodeStringToInteger(&ustrCdRomId, 10, &id);
                        UserAssert(id >= 0 && id < NUM_MEDIA_EVENTS);
                        wcDriveCache[id] = szDrive[0];

                            //Initially set State to Unknown
                        aDriveState[id] = DS_UNKNOWN;

                        /*
                         * If this is the device that notified us, remember its
                         * drive letter so we can broadcase WM_DEVICECHANGE
                         */
                        if (uidCdRom == id) {
                            wcDrive  = szDrive[0];
                        }
                    }
                }
            }

            /*
             * Try the next drive
             */
            szDrive[0] = szDrive[0] + 1;
            szDevice[4] = szDevice[4] + 1;
            dwDriveMask <<= 1;
            --dwDriveCount;
        }
    }

    /*
     * If we found a logical drive, determine the media state for the drive
     * and broadcast the WM_DEVICECHANGE notification.
     */
    if (wcDrive) {
        /*
         * Get the Media status of this drive.  Assume media is not
         * present in the case of an error.
         */
        szDevice[4] = wcDrive;

        hDevice = CreateFile(szDevice,
                             GENERIC_READ,
                             FILE_SHARE_READ,
                             NULL,
                             OPEN_EXISTING,
                             FILE_ATTRIBUTE_NORMAL,
                             NULL);
        if (hDevice == INVALID_HANDLE_VALUE) {
#ifdef DEBUG
        KdPrint(("        CreateFile( '%ls' ) Failed. Error %lx\n",
                szDevice,GetLastError()));
#endif
            return;
        }

        /*
         * Loop and check the CD-ROM to see if media is available.  We need
         * this loop because some CD-ROM drives notify us that media has
         * arrived before the drive has recognized that it had new media.
         */
        for (nCurrentTry = 0; nCurrentTry < MAX_TRIES; nCurrentTry++) {

            /*
             * See if media is present
             */
            bResult = (DWORD)DeviceIoControl(hDevice,
                                             IOCTL_DISK_CHECK_VERIFY,
                                             NULL,
                                             0,
                                             NULL,
                                             0,
                                             &cb,
                                             NULL);

            if (bResult) {
                /*
                 * Media is present, change the state to Inserted.
                 */
                aDriveState[uidCdRom] = DS_INSERTED;
                break;
            }

            /*
             * Media wasn't present, so we need to look at GetLastError() to see
             * if DeviceIoControl() failed.  If so we may want to try again.
             */
            if (GetLastError() == ERROR_NOT_READY) {
                Sleep(500); // 1/2 second

                /*
                * We only want to retry if we the prev State was UNKNOWN or
                * EJECTED. If the previous State was INSERTED it means that
                * this event is the removal event
                */
                if(aDriveState[uidCdRom]== DS_UNKNOWN ||
                        aDriveState[uidCdRom] == DS_EJECTED) {
                    continue;

                }
            }

            /*
             * Call failed.  Assume worst case and say the media has been removed.
             */
            aDriveState[uidCdRom] = DS_EJECTED;
            break;
        }

        /*
         * Close the handle to the CD-ROM device
         */
        CloseHandle(hDevice);

        /*
         * Initialize the structures used for BroadcastSystemMessage
         */
        dbcvInfo.dbcv_size = sizeof(dbcvInfo);
        dbcvInfo.dbcv_devicetype = DBT_DEVTYP_VOLUME;
        dbcvInfo.dbcv_reserved = 0;
        dbcvInfo.dbcv_flags = DBTF_MEDIA;
        dbcvInfo.dbcv_unitmask = (1 << (wcDrive - L'A'));

        dwRecipients = BSM_ALLCOMPONENTS | BSM_ALLDESKTOPS;

        /*
         * Temporarily we must assign this thread to a desktop so we can
         * call USER's BroascastSystemMessage() routine.  We call the
         * private SetThreadDesktopToDefault() to assign ourselves to the
         * desktop that is currently receiving input.
         */
        Status = NtUserSetInformationThread(NtCurrentThread(),
                                            UserThreadUseActiveDesktop,
                                            NULL, 0);
        if (NT_SUCCESS(Status)) {
            /*
             * Broadcast the message
             */
            BroadcastSystemMessage(BSF_FORCEIFHUNG,
                                   &dwRecipients,
                                   WM_DEVICECHANGE,
// HACK: need to or 0x8000 in wParam
//       because this is a flag to let
//       BSM know that lParam is a pointer
//       to a data structure.
                                   0x8000 | ((bResult) ? DBT_DEVICEARRIVAL : DBT_DEVICEREMOVECOMPLETE),
                                   (LPARAM)&dbcvInfo);

#ifdef DEBUG
        KdPrint(("        Message Broadcast for '%lc:'\n", wcDrive));
#endif
            /*
             * Set our thread's desktop back to NULL.  This will decrement
             * the desktop's reference count.
             */
            hDevice = NULL;
            NtUserSetInformationThread(NtCurrentThread(),
                                       UserThreadUseDesktop,
                                       &hDevice, // hDevice = NULL
                                       sizeof(HANDLE));
        }
    }
}
Example #17
0
VOID
LineInputKeyDown(PCONSRV_CONSOLE Console,
                 PUNICODE_STRING ExeName,
                 KEY_EVENT_RECORD *KeyEvent)
{
    UINT Pos = Console->LinePos;
    UNICODE_STRING Entry;

    /*
     * First, deal with control keys...
     */

    switch (KeyEvent->wVirtualKeyCode)
    {
    case VK_ESCAPE:
    {
        /* Clear entire line */
        LineInputSetPos(Console, 0);
        LineInputEdit(Console, Console->LineSize, 0, NULL);

        // TESTS!!
        if (Popup)
        {
            DestroyPopupWindow(Popup);
            Popup = NULL;
        }
        return;
    }

    case VK_HOME:
    {
        /* Move to start of line. With CTRL, erase everything left of cursor */
        LineInputSetPos(Console, 0);
        if (KeyEvent->dwControlKeyState & (LEFT_CTRL_PRESSED | RIGHT_CTRL_PRESSED))
            LineInputEdit(Console, Pos, 0, NULL);
        return;
    }

    case VK_END:
    {
        /* Move to end of line. With CTRL, erase everything right of cursor */
        if (KeyEvent->dwControlKeyState & (LEFT_CTRL_PRESSED | RIGHT_CTRL_PRESSED))
            LineInputEdit(Console, Console->LineSize - Pos, 0, NULL);
        else
            LineInputSetPos(Console, Console->LineSize);
        return;
    }

    case VK_LEFT:
    {
        /* Move left. With CTRL, move to beginning of previous word */
        if (KeyEvent->dwControlKeyState & (LEFT_CTRL_PRESSED | RIGHT_CTRL_PRESSED))
        {
            while (Pos > 0 && Console->LineBuffer[Pos - 1] == L' ') Pos--;
            while (Pos > 0 && Console->LineBuffer[Pos - 1] != L' ') Pos--;
        }
        else
        {
            Pos -= (Pos > 0);
        }
        LineInputSetPos(Console, Pos);
        return;
    }

    case VK_RIGHT:
    case VK_F1:
    {
        /* Move right. With CTRL, move to beginning of next word */
        if (KeyEvent->dwControlKeyState & (LEFT_CTRL_PRESSED | RIGHT_CTRL_PRESSED))
        {
            while (Pos < Console->LineSize && Console->LineBuffer[Pos] != L' ') Pos++;
            while (Pos < Console->LineSize && Console->LineBuffer[Pos] == L' ') Pos++;
            LineInputSetPos(Console, Pos);
        }
        else
        {
            /* Recall one character (but don't overwrite current line) */
            HistoryGetCurrentEntry(Console, ExeName, &Entry);
            if (Pos < Console->LineSize)
                LineInputSetPos(Console, Pos + 1);
            else if (Pos * sizeof(WCHAR) < Entry.Length)
                LineInputEdit(Console, 0, 1, &Entry.Buffer[Pos]);
        }
        return;
    }

    case VK_INSERT:
    {
        /* Toggle between insert and overstrike */
        Console->LineInsertToggle = !Console->LineInsertToggle;
        TermSetCursorInfo(Console, Console->ActiveBuffer);
        return;
    }

    case VK_DELETE:
    {
        /* Remove character to right of cursor */
        if (Pos != Console->LineSize)
            LineInputEdit(Console, 1, 0, NULL);
        return;
    }

    case VK_PRIOR:
    {
        /* Recall first history entry */
        LineInputRecallHistory(Console, ExeName, -((WORD)-1));
        return;
    }

    case VK_NEXT:
    {
        /* Recall last history entry */
        LineInputRecallHistory(Console, ExeName, +((WORD)-1));
        return;
    }

    case VK_UP:
    case VK_F5:
    {
        /*
         * Recall previous history entry. On first time, actually recall the
         * current (usually last) entry; on subsequent times go back.
         */
        LineInputRecallHistory(Console, ExeName, Console->LineUpPressed ? -1 : 0);
        Console->LineUpPressed = TRUE;
        return;
    }

    case VK_DOWN:
    {
        /* Recall next history entry */
        LineInputRecallHistory(Console, ExeName, +1);
        return;
    }

    case VK_F3:
    {
        /* Recall remainder of current history entry */
        HistoryGetCurrentEntry(Console, ExeName, &Entry);
        if (Pos * sizeof(WCHAR) < Entry.Length)
        {
            UINT InsertSize = (Entry.Length / sizeof(WCHAR) - Pos);
            UINT DeleteSize = min(Console->LineSize - Pos, InsertSize);
            LineInputEdit(Console, DeleteSize, InsertSize, &Entry.Buffer[Pos]);
        }
        return;
    }

    case VK_F6:
    {
        /* Insert a ^Z character */
        KeyEvent->uChar.UnicodeChar = 26;
        break;
    }

    case VK_F7:
    {
        if (KeyEvent->dwControlKeyState & (LEFT_ALT_PRESSED | RIGHT_ALT_PRESSED))
            HistoryDeleteCurrentBuffer(Console, ExeName);
        else
        {
            if (Popup) DestroyPopupWindow(Popup);
            Popup = HistoryDisplayCurrentHistory(Console, ExeName);
        }
        return;
    }

    case VK_F8:
    {
        UNICODE_STRING EntryFound;

        Entry.Length = Console->LinePos * sizeof(WCHAR); // == Pos * sizeof(WCHAR)
        Entry.Buffer = Console->LineBuffer;

        if (HistoryFindEntryByPrefix(Console, ExeName, &Entry, &EntryFound))
        {
            LineInputEdit(Console, Console->LineSize - Pos,
                          EntryFound.Length / sizeof(WCHAR) - Pos,
                          &EntryFound.Buffer[Pos]);
            /* Cursor stays where it was */
            LineInputSetPos(Console, Pos);
        }

        return;
    }
#if 0
    {
        PHISTORY_BUFFER Hist;
        INT HistPos;

        /* Search for history entries starting with input. */
        Hist = HistoryCurrentBuffer(Console, ExeName);
        if (!Hist || Hist->NumEntries == 0) return;

        /*
         * Like Up/F5, on first time start from current (usually last) entry,
         * but on subsequent times start at previous entry.
         */
        if (Console->LineUpPressed)
            Hist->Position = (Hist->Position ? Hist->Position : Hist->NumEntries) - 1;
        Console->LineUpPressed = TRUE;

        Entry.Length = Console->LinePos * sizeof(WCHAR); // == Pos * sizeof(WCHAR)
        Entry.Buffer = Console->LineBuffer;

        /*
         * Keep going backwards, even wrapping around to the end,
         * until we get back to starting point.
         */
        HistPos = Hist->Position;
        do
        {
            if (RtlPrefixUnicodeString(&Entry, &Hist->Entries[HistPos], FALSE))
            {
                Hist->Position = HistPos;
                LineInputEdit(Console, Console->LineSize - Pos,
                              Hist->Entries[HistPos].Length / sizeof(WCHAR) - Pos,
                              &Hist->Entries[HistPos].Buffer[Pos]);
                /* Cursor stays where it was */
                LineInputSetPos(Console, Pos);
                return;
            }
            if (--HistPos < 0) HistPos += Hist->NumEntries;
        } while (HistPos != Hist->Position);

        return;
    }
#endif

    return;
    }


    /*
     * OK, we deal with normal keys, we can continue...
     */

    if (KeyEvent->uChar.UnicodeChar == L'\b' && GetConsoleInputBufferMode(Console) & ENABLE_PROCESSED_INPUT)
    {
        /* backspace handling - if processed input enabled then we handle it here
         * otherwise we treat it like a normal char. */
        if (Pos > 0)
        {
            LineInputSetPos(Console, Pos - 1);
            LineInputEdit(Console, 1, 0, NULL);
        }
    }
    else if (KeyEvent->uChar.UnicodeChar == L'\r')
    {
        Entry.Length = Entry.MaximumLength = Console->LineSize * sizeof(WCHAR);
        Entry.Buffer = Console->LineBuffer;
        HistoryAddEntry(Console, ExeName, &Entry);

        /* TODO: Expand aliases */
        DPRINT1("TODO: Expand aliases\n");

        LineInputSetPos(Console, Console->LineSize);
        Console->LineBuffer[Console->LineSize++] = L'\r';
        if (GetConsoleInputBufferMode(Console) & ENABLE_ECHO_INPUT)
        {
            if (GetType(Console->ActiveBuffer) == TEXTMODE_BUFFER)
            {
                TermWriteStream(Console, (PTEXTMODE_SCREEN_BUFFER)(Console->ActiveBuffer), L"\r", 1, TRUE);
            }
        }

        /*
         * Add \n if processed input. There should usually be room for it,
         * but an exception to the rule exists: the buffer could have been
         * pre-filled with LineMaxSize - 1 characters.
         */
        if (GetConsoleInputBufferMode(Console) & ENABLE_PROCESSED_INPUT &&
                Console->LineSize < Console->LineMaxSize)
        {
            Console->LineBuffer[Console->LineSize++] = L'\n';
            if (GetConsoleInputBufferMode(Console) & ENABLE_ECHO_INPUT)
            {
                if (GetType(Console->ActiveBuffer) == TEXTMODE_BUFFER)
                {
                    TermWriteStream(Console, (PTEXTMODE_SCREEN_BUFFER)(Console->ActiveBuffer), L"\n", 1, TRUE);
                }
            }
        }
        Console->LineComplete = TRUE;
        Console->LinePos = 0;
    }
    else if (KeyEvent->uChar.UnicodeChar != L'\0')
    {
        if (KeyEvent->uChar.UnicodeChar < 0x20 &&
                Console->LineWakeupMask & (1 << KeyEvent->uChar.UnicodeChar))
        {
            /* Control key client wants to handle itself (e.g. for tab completion) */
            Console->LineBuffer[Console->LineSize++] = L' ';
            Console->LineBuffer[Console->LinePos] = KeyEvent->uChar.UnicodeChar;
            Console->LineComplete = TRUE;
            Console->LinePos = 0;
        }
        else
        {
            /* Normal character */
            BOOL Overstrike = !Console->LineInsertToggle && (Console->LinePos != Console->LineSize);
            DPRINT("Overstrike = %s\n", Overstrike ? "true" : "false");
            LineInputEdit(Console, (Overstrike ? 1 : 0), 1, &KeyEvent->uChar.UnicodeChar);
        }
    }
}
Example #18
0
NTSTATUS
LsapDbGetScopeSecret(
    IN PLSAPR_UNICODE_STRING SecretName,
    OUT PBOOLEAN GlobalSecret
    )

/*++

Routine Description:

    This function checks the scope of a Secret name.  Secrets have either
    Global or Local Scope.

    Global Secrets are Secrets that are normally present on all DC's for a
    Domain.  They are replicated from PDC's to BDC's.  On BDC's, only a
    Trusted Client such as a replicator can create, update or delete Global
    Secrets.  Global Secrets are identified as Secrets whose name begins
    with a designated prefix.

    Local Secrets are Secrets that are private to a specific machine.  They
    are not replicated.  Normal non-trusted clients may create, update or
    delete Local Secrets.  Local Secrets are idientified as Secrets whose
    name does not begin with a designated prefix.

Arguments:

    SecretName - Pointer to Unicode String containing the name of the
        Secret to be checked.

    GlobalSecret - Receives a Boolean indicating

Return Values:

    NTSTATUS - Standard Nt Result Code

        STATUS_SUCCESS - The Secret name is valid

        STATUS_INVALID_PARAMETER - The Secret Name is invalid in such a
            way as to prevent scope determination.
--*/

{
    NTSTATUS Status = STATUS_SUCCESS;
    UNICODE_STRING GlobalPrefix;
    BOOLEAN OutputGlobalSecret = FALSE;

    //
    // Initialize a Unicode String with the Global Secret name Prefix.
    //

    RtlInitUnicodeString( &GlobalPrefix, LSA_GLOBAL_SECRET_PREFIX );

    //
    // Now check if the given Name has the Global Prefix.
    //

    if (RtlPrefixUnicodeString( &GlobalPrefix, (PUNICODE_STRING) SecretName, TRUE)) {

        OutputGlobalSecret = TRUE;
    }

    *GlobalSecret = OutputGlobalSecret;

    return(Status);
}