Ejemplo n.º 1
0
NTSTATUS
FindHardDiskForPartition(PUNICODE_STRING pNameUnicodeString, PWCHAR pOutRequest, ULONG OutRequestSize, ULONG *pRetSize)
{
	NTSTATUS ntRetStatus = STATUS_NOT_FOUND;
	NTSTATUS ntStatus;

	BYTE					cou;
	OBJECT_ATTRIBUTES	ObjAttr;
	HANDLE				hDirectoryObject;
	BOOLEAN				First;
	POBJECT_NAMETYPE_INFO p;
	HANDLE				DrvHandle;
	PDRIVER_OBJECT		pDrv;
	UNICODE_STRING		Name;
	PWCHAR				DrvName;
	PWCHAR				DriverStr=L"Partition";
	WCHAR				Dir[128];
	ULONG				RegionSize;
	PMY_QUERY_DIRECTORY_STRUCT qds;
	
	qds = NULL;
	RegionSize = sizeof(MY_QUERY_DIRECTORY_STRUCT);

	if(!NT_SUCCESS(ntStatus = ZwAllocateVirtualMemory((HANDLE)-1, (PVOID*) &qds, 0, &RegionSize, // ^ - Whistler beta 2 doesn't work with 8
		MEM_COMMIT,PAGE_READWRITE)))
	{
		DbPrint(DC_LLDISKIO, DL_ERROR,("ZwAllocateVirtualMemory fail. Status=%x\n", ntStatus));
	}
	else
	{
		PWCHAR pdrvid;
		for(cou = 0; cou <= 9 && ntRetStatus != STATUS_SUCCESS; cou++)
		{
			wcscpy(Dir, L"\\Device\\Harddisk0");
			pdrvid = &Dir[wcslen(Dir) - 1];
			*(BYTE*)pdrvid += cou;
			
			RtlInitUnicodeString(&Name, Dir);
			InitializeObjectAttributes(&ObjAttr, &Name, OBJ_CASE_INSENSITIVE, NULL, NULL);
			ntStatus=ZwOpenDirectoryObject(&hDirectoryObject, DIRECTORY_QUERY, &ObjAttr);
			if(NT_SUCCESS(ntStatus))
			{
				First=TRUE;
				DrvName=Dir+wcslen(Dir);
				*DrvName++='\\';
				while(NtQueryDirectoryObject(hDirectoryObject, &qds->Buffer, QUERY_DIRECTORY_BUFF_SIZE, TRUE, First, 
					&qds->Index, &qds->Retlen) >= 0 && ntRetStatus != STATUS_SUCCESS)
				{
					p=(POBJECT_NAMETYPE_INFO)&qds->Buffer;
					First=FALSE;
					*DrvName=0;
					if(wcsncmp(p->ObjectName.Buffer, DriverStr, 9)) 
						continue;
					else
					{
						HANDLE				hLink;

						InitializeObjectAttributes(&ObjAttr, &p->ObjectName, OBJ_CASE_INSENSITIVE, 
							hDirectoryObject, NULL);
						
						ntStatus = ZwOpenSymbolicLinkObject(&hLink, SYMBOLIC_LINK_QUERY, &ObjAttr);
						if(NT_SUCCESS(ntStatus))
						{
							WCHAR				targetNameBuffer[260];
							UNICODE_STRING      targetNameUnicodeString;

							RtlZeroMemory(targetNameBuffer, sizeof(targetNameBuffer));
							targetNameUnicodeString.Buffer = targetNameBuffer;
							targetNameUnicodeString.MaximumLength = sizeof(targetNameBuffer);
							ntStatus = ZwQuerySymbolicLinkObject(hLink, &targetNameUnicodeString, NULL);
							
							if(NT_SUCCESS(ntStatus) && (RtlCompareUnicodeString(&targetNameUnicodeString, 
								pNameUnicodeString, FALSE) == 0))
							{
								int number = GetHarddiskId(Dir);
								if (number != -1)
								{
									int cou2;
									int drvstrlen;
									char drstr[32];
									sprintf(drstr, "%d", number);
									drvstrlen = strlen(drstr);

									wcscpy(pOutRequest, Dir);
									wcscat(pOutRequest, L"DR");
									pdrvid = &pOutRequest[wcslen(pOutRequest) - 1] + 1;
									
									for (cou2 = 0; cou2 < drvstrlen; cou2++)
									{
										*pdrvid = (WCHAR) (drstr[cou2]);
										pdrvid++;
									}
									*pdrvid = 0;

									DbPrint(DC_LLDISKIO, DL_INFO, ("FindHardDiskForPartition found %S\n", pOutRequest));
									
									*pRetSize = (wcslen(pOutRequest) + 1 ) * 2;
									ntRetStatus = STATUS_SUCCESS;
								}
							}
							ZwClose(hLink);
						}
					}

				}
				ZwClose(hDirectoryObject);
			}
		}
	}
	RegionSize = 0;

	_pfZwFreeVirtualMemory((HANDLE)-1,(PVOID*) &qds,&RegionSize,MEM_RELEASE);

	return ntRetStatus;
}
Ejemplo n.º 2
0
/**
 * Fetches more data from the file system.
 *
 * @returns IPRT status code
 * @param   pThis       The directory instance data.
 */
static int rtDirNtFetchMore(PRTDIR pThis)
{
    Assert(!pThis->fDataUnread);

    /*
     * Allocate the buffer the first time around.
     * We do this in lazy fashion as some users of RTDirOpen will not actually
     * list any files, just open it for various reasons.
     */
    bool fFirst = false;
    if (!pThis->pabBuffer)
    {
        fFirst = false;
        pThis->cbBufferAlloc = _256K;
        pThis->pabBuffer = (uint8_t *)RTMemAlloc(pThis->cbBufferAlloc);
        if (!pThis->pabBuffer)
        {
            do
            {
                pThis->cbBufferAlloc /= 4;
                pThis->pabBuffer = (uint8_t *)RTMemAlloc(pThis->cbBufferAlloc);
            } while (pThis->pabBuffer == NULL && pThis->cbBufferAlloc > _4K);
            if (!pThis->pabBuffer)
                return VERR_NO_MEMORY;
        }
    }

    /*
     * Read more.
     */
    NTSTATUS rcNt;
    IO_STATUS_BLOCK Ios = MY_IO_STATUS_BLOCK_INITIALIZER;
    if (pThis->enmInfoClass != (FILE_INFORMATION_CLASS)0)
    {
#ifdef IPRT_WITH_NT_PATH_PASSTHRU
        if (pThis->enmInfoClass == FileMaximumInformation)
        {
            Ios.Information = 0;
            Ios.Status = rcNt = NtQueryDirectoryObject(pThis->hDir,
                                                       pThis->pabBuffer,
                                                       pThis->cbBufferAlloc,
                                                       RTDIR_NT_SINGLE_RECORD /*ReturnSingleEntry */,
                                                       FALSE /*RestartScan*/,
                                                       &pThis->uObjDirCtx,
                                                       (PULONG)&Ios.Information);
        }
        else
#endif
            rcNt = NtQueryDirectoryFile(pThis->hDir,
                                        NULL /* Event */,
                                        NULL /* ApcRoutine */,
                                        NULL /* ApcContext */,
                                        &Ios,
                                        pThis->pabBuffer,
                                        pThis->cbBufferAlloc,
                                        pThis->enmInfoClass,
                                        RTDIR_NT_SINGLE_RECORD /*ReturnSingleEntry */,
                                        pThis->pNtFilterStr,
                                        FALSE /*RestartScan */);
    }
    else
    {
        /*
         * The first time around we have figure which info class we can use.
         * We prefer one which gives us file IDs, but we'll settle for less.
         */
        pThis->enmInfoClass = FileIdBothDirectoryInformation;
        rcNt = NtQueryDirectoryFile(pThis->hDir,
                                    NULL /* Event */,
                                    NULL /* ApcRoutine */,
                                    NULL /* ApcContext */,
                                    &Ios,
                                    pThis->pabBuffer,
                                    pThis->cbBufferAlloc,
                                    pThis->enmInfoClass,
                                    RTDIR_NT_SINGLE_RECORD /*ReturnSingleEntry */,
                                    pThis->pNtFilterStr,
                                    FALSE /*RestartScan */);
        if (!NT_SUCCESS(rcNt))
        {
            pThis->enmInfoClass = FileBothDirectoryInformation;
            rcNt = NtQueryDirectoryFile(pThis->hDir,
                                        NULL /* Event */,
                                        NULL /* ApcRoutine */,
                                        NULL /* ApcContext */,
                                        &Ios,
                                        pThis->pabBuffer,
                                        pThis->cbBufferAlloc,
                                        pThis->enmInfoClass,
                                        RTDIR_NT_SINGLE_RECORD /*ReturnSingleEntry */,
                                        pThis->pNtFilterStr,
                                        FALSE /*RestartScan */);
        }
    }
    if (!NT_SUCCESS(rcNt))
    {
        if (rcNt == STATUS_NO_MORE_FILES || rcNt == STATUS_NO_MORE_ENTRIES)
            return VERR_NO_MORE_FILES;
        return RTErrConvertFromNtStatus(rcNt);
    }
    Assert(Ios.Information > sizeof(*pThis->uCurData.pBoth));

    /*
     * Set up the data members.
     */
    pThis->uCurData.u  = (uintptr_t)pThis->pabBuffer;
    pThis->cbBuffer    = Ios.Information;

    int rc = rtDirNtCheckRecord(pThis);
    pThis->fDataUnread = RT_SUCCESS(rc);

    return rc;
}
Ejemplo n.º 3
0
int GetHarddiskId(PWCHAR pwchDir)
{
	NTSTATUS			ntStatus;
	int					nRet = -1;

	OBJECT_ATTRIBUTES	ObjAttr;
	HANDLE				hDirectoryObject;
	UNICODE_STRING		Name;
	
	WCHAR				DriverStr[32];
	PWCHAR				pdrvid;
	int					len ;

	PMY_QUERY_DIRECTORY_STRUCT	qds;
	POBJECT_NAMETYPE_INFO		p;
	ULONG						RegionSize;

	int cou;
	
	qds = NULL;
	RegionSize = sizeof(MY_QUERY_DIRECTORY_STRUCT);

	if(!NT_SUCCESS(ntStatus = ZwAllocateVirtualMemory((HANDLE)-1, (PVOID*) &qds, 0, &RegionSize, 
		MEM_COMMIT,PAGE_READWRITE)))
	{
		return nRet;
	}

	wcscpy(DriverStr, L"DR0");
	len = wcslen(DriverStr);
	pdrvid = &DriverStr[len - 1];

	RtlInitUnicodeString(&Name, pwchDir);
	Name.Length -= sizeof(WCHAR);
	InitializeObjectAttributes(&ObjAttr, &Name, OBJ_CASE_INSENSITIVE, NULL, NULL);
	ntStatus = ZwOpenDirectoryObject(&hDirectoryObject, DIRECTORY_QUERY, &ObjAttr);

	if(NT_SUCCESS(ntStatus))
	{
		BOOLEAN First = TRUE;
		
		while(NtQueryDirectoryObject(hDirectoryObject, &qds->Buffer, QUERY_DIRECTORY_BUFF_SIZE, TRUE, First, 
			&qds->Index, &qds->Retlen) >= 0 && nRet == -1)
		{
			PWCHAR obj_name;
			int tmp_len;
			p = (POBJECT_NAMETYPE_INFO)&qds->Buffer;
			First = FALSE;
			
			obj_name = p->ObjectName.Buffer;
			tmp_len = p->ObjectName.Length / sizeof(WCHAR);

			if (tmp_len >= 3)
			{
				// TAK POLUCHILOS! :)
				if (obj_name[0] == L'D' && obj_name[1] == L'R')
				{
					BOOLEAN bisdigit = TRUE;
					int cou2;
					int ntmp = 0;
					for (cou2 = 2; cou2 < tmp_len; cou2++)
					{
						if (obj_name[cou2] < L'0' || obj_name[cou2] > L'9')
						{
							bisdigit = FALSE;
							break;
						}
						ntmp = ntmp * 10 + (obj_name[cou2] - L'0');
					}

					if (bisdigit)
						nRet = ntmp;
				}
			}
		}

		ZwClose(hDirectoryObject);
	}

	_pfZwFreeVirtualMemory((HANDLE)-1,(PVOID*) &qds, &RegionSize,MEM_RELEASE);
	return nRet;
}
Ejemplo n.º 4
0
VOID
DumpObjectDirs(
    IN PCH DirName,
    IN ULONG Level
    )
{
    OBJECT_ATTRIBUTES ObjectAttributes;
    STRING Name;
    HANDLE Handle;
    ULONG Context, Length;
    NTSTATUS Status;
    BOOLEAN RestartScan;
    POBJECT_DIRECTORY_INFORMATION DirInfo;
    CHAR DirInfoBuffer[ 256 ];
    CHAR SubDirName[ 128 ];
    STRING LinkName;
    STRING LinkTarget;
    HANDLE LinkHandle;

    RtlInitString( &Name, DirName );
    InitializeObjectAttributes( &ObjectAttributes,
                                &Name,
                                OBJ_OPENIF | OBJ_CASE_INSENSITIVE,
                                NULL,
                                NULL
                              );
    NtCreateDirectoryObject( &Handle,
                             DIRECTORY_ALL_ACCESS,
                             &ObjectAttributes
                           );

    DirInfo = (POBJECT_DIRECTORY_INFORMATION)&DirInfoBuffer;
    RestartScan = TRUE;
    while (TRUE) {
        Status = NtQueryDirectoryObject( Handle,
                                         (PVOID)DirInfo,
                                         sizeof( DirInfoBuffer ),
                                         TRUE,
                                         RestartScan,
                                         &Context,
                                         &Length
                                       );
        if (!NT_SUCCESS( Status )) {
            break;
            }

        DbgPrint( "%s%s%Z - %Z",
                 DirName,
                 Level ? "\\" : "",
                 &DirInfo->Name,
                 &DirInfo->TypeName
                 );
        if (RtlEqualString( &DirInfo->TypeName, &DirTypeName, TRUE )) {
            DbgPrint( "\n" );
            strcpy( SubDirName, DirName );
            if (Level) {
                strcat( SubDirName, "\\" );
                }
            strcat( SubDirName, DirInfo->Name.Buffer );
            DumpObjectDirs( SubDirName, Level+1 );
            }
        else
        if (RtlEqualString( &DirInfo->TypeName, &LinkTypeName, TRUE )) {
            strcpy( SubDirName, DirName );
            if (Level) {
                strcat( SubDirName, "\\" );
                }
            strcat( SubDirName, DirInfo->Name.Buffer );
            RtlInitString( &LinkName, SubDirName );
            InitializeObjectAttributes( &ObjectAttributes,
                                        &LinkName,
                                        0,
                                        NULL,
                                        NULL
                                      );
            Status = NtOpenSymbolicLinkObject( &LinkHandle,
                                               SYMBOLIC_LINK_ALL_ACCESS,
                                               &ObjectAttributes
                                             );
            if (!NT_SUCCESS( Status )) {
                DbgPrint( " - unable to open symbolic link (%X)\n", Status  );
                }
            else {
                LinkTarget.MaximumLength = sizeof( SubDirName );
                LinkTarget.Length = 0;
                LinkTarget.Buffer = SubDirName;
                Status = NtQuerySymbolicLinkObject( LinkHandle,
                                                    &LinkTarget
                                                  );
                if (!NT_SUCCESS( Status )) {
                    DbgPrint( " - unable to query symbolic link target (%X)\n", Status );
                    }
                else {
                    DbgPrint( " => %Z\n", &LinkTarget );
                    }

                NtClose( LinkHandle );
                }
            }
        else {
            DbgPrint( "\n" );
            }

        RestartScan = FALSE;
        }

    NtClose( Handle );
}
Ejemplo n.º 5
0
/*
 * @implemented
 */
DWORD
WINAPI
QueryDosDeviceW(
    LPCWSTR lpDeviceName,
    LPWSTR lpTargetPath,
    DWORD ucchMax
    )
{
  POBJECT_DIRECTORY_INFORMATION DirInfo;
  OBJECT_ATTRIBUTES ObjectAttributes;
  UNICODE_STRING UnicodeString;
  HANDLE DirectoryHandle;
  HANDLE DeviceHandle;
  ULONG ReturnLength;
  ULONG NameLength;
  ULONG Length;
  ULONG Context;
  BOOLEAN RestartScan;
  NTSTATUS Status;
  UCHAR Buffer[512];
  PWSTR Ptr;

  /* Open the '\??' directory */
  RtlInitUnicodeString (&UnicodeString,
			L"\\??");
  InitializeObjectAttributes (&ObjectAttributes,
			      &UnicodeString,
			      OBJ_CASE_INSENSITIVE,
			      NULL,
			      NULL);
  Status = NtOpenDirectoryObject (&DirectoryHandle,
				  DIRECTORY_QUERY,
				  &ObjectAttributes);
  if (!NT_SUCCESS (Status))
  {
    WARN ("NtOpenDirectoryObject() failed (Status %lx)\n", Status);
    BaseSetLastNTError (Status);
    return 0;
  }

  Length = 0;

  if (lpDeviceName != NULL)
  {
    /* Open the lpDeviceName link object */
    RtlInitUnicodeString (&UnicodeString,
			  (PWSTR)lpDeviceName);
    InitializeObjectAttributes (&ObjectAttributes,
				&UnicodeString,
				OBJ_CASE_INSENSITIVE,
				DirectoryHandle,
				NULL);
    Status = NtOpenSymbolicLinkObject (&DeviceHandle,
				       SYMBOLIC_LINK_QUERY,
				       &ObjectAttributes);
    if (!NT_SUCCESS (Status))
    {
      WARN ("NtOpenSymbolicLinkObject() failed (Status %lx)\n", Status);
      NtClose (DirectoryHandle);
      BaseSetLastNTError (Status);
      return 0;
    }

    /* Query link target */
    UnicodeString.Length = 0;
    UnicodeString.MaximumLength = (USHORT)ucchMax * sizeof(WCHAR);
    UnicodeString.Buffer = lpTargetPath;

    ReturnLength = 0;
    Status = NtQuerySymbolicLinkObject (DeviceHandle,
					&UnicodeString,
					&ReturnLength);
    NtClose (DeviceHandle);
    NtClose (DirectoryHandle);
    if (!NT_SUCCESS (Status))
    {
      WARN ("NtQuerySymbolicLinkObject() failed (Status %lx)\n", Status);
      BaseSetLastNTError (Status);
      return 0;
    }

    TRACE ("ReturnLength: %lu\n", ReturnLength);
    TRACE ("TargetLength: %hu\n", UnicodeString.Length);
    TRACE ("Target: '%wZ'\n", &UnicodeString);

    Length = UnicodeString.Length / sizeof(WCHAR);
    if (Length < ucchMax)
    {
      /* Append null-charcter */
      lpTargetPath[Length] = UNICODE_NULL;
      Length++;
    }
    else
    {
      TRACE ("Buffer is too small\n");
      BaseSetLastNTError (STATUS_BUFFER_TOO_SMALL);
      return 0;
    }
  }
  else
  {
    RestartScan = TRUE;
    Context = 0;
    Ptr = lpTargetPath;
    DirInfo = (POBJECT_DIRECTORY_INFORMATION)Buffer;

    while (TRUE)
    {
      Status = NtQueryDirectoryObject (DirectoryHandle,
				       Buffer,
				       sizeof (Buffer),
				       TRUE,
				       RestartScan,
				       &Context,
				       &ReturnLength);
      if (!NT_SUCCESS(Status))
      {
	if (Status == STATUS_NO_MORE_ENTRIES)
	{
	  /* Terminate the buffer */
	  *Ptr = UNICODE_NULL;
	  Length++;

	  Status = STATUS_SUCCESS;
	}
	else
	{
	  Length = 0;
	}
	BaseSetLastNTError (Status);
	break;
      }

      if (!wcscmp (DirInfo->TypeName.Buffer, L"SymbolicLink"))
      {
	TRACE ("Name: '%wZ'\n", &DirInfo->Name);

	NameLength = DirInfo->Name.Length / sizeof(WCHAR);
	if (Length + NameLength + 1 >= ucchMax)
	{
	  Length = 0;
	  BaseSetLastNTError (STATUS_BUFFER_TOO_SMALL);
	  break;
	}

	memcpy (Ptr,
		DirInfo->Name.Buffer,
		DirInfo->Name.Length);
	Ptr += NameLength;
	Length += NameLength;
	*Ptr = UNICODE_NULL;
	Ptr++;
	Length++;
      }

      RestartScan = FALSE;
    }

    NtClose (DirectoryHandle);
  }

  return Length;
}
/**
 * Deal with getting info about something that could be in a directory object.
 *
 * @returns IPRT status code
 * @param   pObjAttr        The NT object attribute.
 * @param   pObjInfo        Where to return the info.
 * @param   enmAddAttr      Which extra attributes to get (/fake).
 * @param   fFlags          The flags.
 * @param   pvBuf           Query buffer space.
 * @param   cbBuf           Size of the buffer.  ASSUMES lots of space.
 * @param   rcNtCaller      The status code that got us here.
 */
static int rtPathNtQueryInfoInDirectoryObject(OBJECT_ATTRIBUTES *pObjAttr, PRTFSOBJINFO pObjInfo,
                                              RTFSOBJATTRADD enmAddAttr, uint32_t fFlags,
                                              void *pvBuf, size_t cbBuf, NTSTATUS rcNtCaller)
{
    RT_NOREF(fFlags);

    /*
     * Special case: Root dir.
     */
    if (   pObjAttr->RootDirectory == NULL
        && pObjAttr->ObjectName->Length == sizeof(RTUTF16)
        && pObjAttr->ObjectName->Buffer[0] == '\\')
    {
        pObjInfo->cbObject    = 0;
        pObjInfo->cbAllocated = 0;
        RTTimeSpecSetNtTime(&pObjInfo->BirthTime,         0);
        RTTimeSpecSetNtTime(&pObjInfo->AccessTime,        0);
        RTTimeSpecSetNtTime(&pObjInfo->ModificationTime,  0);
        RTTimeSpecSetNtTime(&pObjInfo->ChangeTime,        0);
        pObjInfo->Attr.fMode = RTFS_DOS_DIRECTORY | RTFS_TYPE_DIRECTORY | 0777;
        return rtPathNtQueryInfoFillInDummyData(VINF_SUCCESS, pObjInfo, enmAddAttr);
    }

    /*
     * We must open and scan the parent directory object.
     */
    UNICODE_STRING NtDirName;
    UNICODE_STRING NtDirEntry;
    ntPathNtSplitName(pObjAttr->ObjectName, &NtDirName, &NtDirEntry, true /*fNoParentDirSlash*/);

    while (   NtDirEntry.Length > sizeof(RTUTF16)
           && NtDirEntry.Buffer[NtDirEntry.Length / sizeof(RTUTF16) - 1] == '\\')
        NtDirEntry.Length -= sizeof(RTUTF16);

    pObjAttr->ObjectName = &NtDirName;
    HANDLE   hDir = RTNT_INVALID_HANDLE_VALUE;
    NTSTATUS rcNt = NtOpenDirectoryObject(&hDir, DIRECTORY_QUERY | DIRECTORY_TRAVERSE, pObjAttr);
    if (NT_SUCCESS(rcNt))
    {
        ULONG uObjDirCtx = 0;
        for (;;)
        {
            ULONG cbReturned = 0;
            rcNt = NtQueryDirectoryObject(hDir,
                                          pvBuf,
                                          (ULONG)cbBuf,
                                          FALSE /*ReturnSingleEntry */,
                                          FALSE /*RestartScan*/,
                                          &uObjDirCtx,
                                          &cbReturned);
            if (!NT_SUCCESS(rcNt))
                break;

            for (POBJECT_DIRECTORY_INFORMATION pObjDir = (POBJECT_DIRECTORY_INFORMATION)pvBuf;
                 pObjDir->Name.Length != 0;
                 pObjDir++)
            {
                if (   pObjDir->Name.Length == NtDirEntry.Length
                    && memcmp(pObjDir->Name.Buffer, NtDirEntry.Buffer, NtDirEntry.Length) == 0)
                {
                    /*
                     * Find it.  Fill in the info we've got and return (see similar code in direnum-r3-nt.cpp).
                     */
                    NtClose(hDir);

                    pObjInfo->cbObject    = 0;
                    pObjInfo->cbAllocated = 0;
                    RTTimeSpecSetNtTime(&pObjInfo->BirthTime,         0);
                    RTTimeSpecSetNtTime(&pObjInfo->AccessTime,        0);
                    RTTimeSpecSetNtTime(&pObjInfo->ModificationTime,  0);
                    RTTimeSpecSetNtTime(&pObjInfo->ChangeTime,        0);

                    if (ARE_UNICODE_STRINGS_EQUAL(&pObjDir->TypeName, L"Directory"))
                        pObjInfo->Attr.fMode = RTFS_DOS_DIRECTORY | RTFS_TYPE_DIRECTORY | 0777;
                    else if (ARE_UNICODE_STRINGS_EQUAL(&pObjDir->TypeName, L"SymbolicLink"))
                        pObjInfo->Attr.fMode = RTFS_DOS_NT_REPARSE_POINT | RTFS_TYPE_SYMLINK | 0777;
                    else if (ARE_UNICODE_STRINGS_EQUAL(&pObjDir->TypeName, L"Device"))
                        pObjInfo->Attr.fMode = RTFS_DOS_NT_DEVICE | RTFS_TYPE_DEV_CHAR | 0666;
                    else
                        pObjInfo->Attr.fMode = RTFS_DOS_NT_NORMAL | RTFS_TYPE_FILE | 0666;

                    pObjInfo->Attr.enmAdditional = enmAddAttr;
                    return rtPathNtQueryInfoFillInDummyData(VINF_SUCCESS, pObjInfo, enmAddAttr);
                }
            }
        }

        NtClose(hDir);
        if (rcNt == STATUS_NO_MORE_FILES || rcNt == STATUS_NO_MORE_ENTRIES || rcNt == STATUS_NO_SUCH_FILE)
            return VERR_FILE_NOT_FOUND;
    }
    else
        return RTErrConvertFromNtStatus(rcNtCaller);
    return RTErrConvertFromNtStatus(rcNt);
}
Ejemplo n.º 7
0
static
DWORD
ScmGetDriverStatus(PSERVICE lpService,
                   LPSERVICE_STATUS lpServiceStatus)
{
    OBJECT_ATTRIBUTES ObjectAttributes;
    UNICODE_STRING DirName;
    HANDLE DirHandle;
    NTSTATUS Status = STATUS_SUCCESS;
    POBJECT_DIRECTORY_INFORMATION DirInfo;
    ULONG BufferLength;
    ULONG DataLength;
    ULONG Index;
    DWORD dwError = ERROR_SUCCESS;
    BOOLEAN bFound = FALSE;
    DWORD dwPreviousState;

    DPRINT1("ScmGetDriverStatus() called\n");

    /* Zero output buffer if any */
    if (lpServiceStatus != NULL)
    {
        memset(lpServiceStatus, 0, sizeof(SERVICE_STATUS));
    }

    /* Select the appropriate object directory based on driver type */
    if (lpService->Status.dwServiceType == SERVICE_KERNEL_DRIVER)
    {
        RtlInitUnicodeString(&DirName, L"\\Driver");
    }
    else // if (lpService->Status.dwServiceType == SERVICE_FILE_SYSTEM_DRIVER)
    {
        ASSERT(lpService->Status.dwServiceType == SERVICE_FILE_SYSTEM_DRIVER);
        RtlInitUnicodeString(&DirName, L"\\FileSystem");
    }

    InitializeObjectAttributes(&ObjectAttributes,
                               &DirName,
                               0,
                               NULL,
                               NULL);

    /* Open the object directory where loaded drivers are */
    Status = NtOpenDirectoryObject(&DirHandle,
                                   DIRECTORY_QUERY | DIRECTORY_TRAVERSE,
                                   &ObjectAttributes);
    if (!NT_SUCCESS(Status))
    {
        DPRINT1("NtOpenDirectoryObject() failed!\n");
        return RtlNtStatusToDosError(Status);
    }

    /* Allocate a buffer big enough for querying the object */
    BufferLength = sizeof(OBJECT_DIRECTORY_INFORMATION) +
                   2 * MAX_PATH * sizeof(WCHAR);
    DirInfo = (OBJECT_DIRECTORY_INFORMATION*) HeapAlloc(GetProcessHeap(),
                        HEAP_ZERO_MEMORY,
                        BufferLength);

    /* Now, start browsing entry by entry */
    Index = 0;
    while (TRUE)
    {
        Status = NtQueryDirectoryObject(DirHandle,
                                        DirInfo,
                                        BufferLength,
                                        TRUE,
                                        FALSE,
                                        &Index,
                                        &DataLength);
        /* End of enumeration, the driver was not found */
        if (Status == STATUS_NO_MORE_ENTRIES)
        {
            DPRINT("No more services\n");
            break;
        }

        /* Other error, fail */
        if (!NT_SUCCESS(Status))
            break;

        DPRINT("Comparing: '%S'  '%wZ'\n", lpService->lpServiceName, &DirInfo->Name);

        /* Compare names to check whether it matches our driver */
        if (_wcsicmp(lpService->lpServiceName, DirInfo->Name.Buffer) == 0)
        {
            /* That's our driver, bail out! */
            DPRINT1("Found: '%S'  '%wZ'\n",
                    lpService->lpServiceName, &DirInfo->Name);
            bFound = TRUE;

            break;
        }
    }

    /* Release resources we don't need */
    HeapFree(GetProcessHeap(),
             0,
             DirInfo);
    NtClose(DirHandle);

    /* Only quit if there's a failure
     * Not having found the driver is legit!
     * It means the driver was registered as a service, but not loaded
     * We have not to fail in that situation, but to return proper status
     */
    if (!NT_SUCCESS(Status) && Status != STATUS_NO_MORE_ENTRIES)
    {
        DPRINT1("Status: %lx\n", Status);
        return RtlNtStatusToDosError(Status);
    }

    /* Now, we have two cases:
     * We found the driver: it means it's running
     * We didn't find the driver: it wasn't running
     */
    if (bFound)
    {
        /* Found, return it's running */

        dwPreviousState = lpService->Status.dwCurrentState;

        /* It is running */
        lpService->Status.dwCurrentState = SERVICE_RUNNING;

        if (dwPreviousState == SERVICE_STOPPED)
        {
            /* Make it run if it was stopped before */
            lpService->Status.dwWin32ExitCode = ERROR_SUCCESS;
            lpService->Status.dwServiceSpecificExitCode = ERROR_SUCCESS;
            lpService->Status.dwControlsAccepted = SERVICE_ACCEPT_STOP;
            lpService->Status.dwCheckPoint = 0;
            lpService->Status.dwWaitHint = 0;
        }

        if (lpService->Status.dwWin32ExitCode == ERROR_SERVICE_NEVER_STARTED)
            lpService->Status.dwWin32ExitCode = ERROR_SUCCESS;
    }
    else
    {
        /* Not found, return it's stopped */

        if (lpService->Status.dwCurrentState == SERVICE_STOP_PENDING)
        {
            /* Stopped successfully */
            lpService->Status.dwWin32ExitCode = ERROR_SUCCESS;
            lpService->Status.dwCurrentState = SERVICE_STOPPED;
            lpService->Status.dwControlsAccepted = 0;
            lpService->Status.dwCheckPoint = 0;
            lpService->Status.dwWaitHint = 0;
        }
        else if (lpService->Status.dwCurrentState == SERVICE_STOPPED)
        {
            /* Don't change the current status */
        }
        else
        {
            lpService->Status.dwWin32ExitCode = ERROR_GEN_FAILURE;
            lpService->Status.dwCurrentState = SERVICE_STOPPED;
            lpService->Status.dwControlsAccepted = 0;
            lpService->Status.dwCheckPoint = 0;
            lpService->Status.dwWaitHint = 0;
        }
    }

    /* Copy service status if required */
    if (lpServiceStatus != NULL)
    {
        RtlCopyMemory(lpServiceStatus,
                      &lpService->Status,
                      sizeof(SERVICE_STATUS));
    }

    DPRINT1("ScmGetDriverStatus() done (Error: %lu)\n", dwError);

    return ERROR_SUCCESS;
}
/**
 * Fetches more data from the file system.
 *
 * @returns IPRT status code
 * @param   pThis       The directory instance data.
 */
static int rtDirNtFetchMore(PRTDIRINTERNAL pThis)
{
    Assert(!pThis->fDataUnread);

    /*
     * Allocate the buffer the first time around.
     * We do this in lazy fashion as some users of RTDirOpen will not actually
     * list any files, just open it for various reasons.
     *
     * We also reduce the buffer size for networked devices as the windows 7-8.1,
     * server 2012, ++ CIFS servers or/and IFSes screws up buffers larger than 64KB.
     * There is an alternative hack below, btw.  We'll leave both in for now.
     */
    bool fFirst = false;
    if (!pThis->pabBuffer)
    {
        pThis->cbBufferAlloc = _256K;
        if (true) /** @todo skip for known local devices, like the boot device? */
        {
            IO_STATUS_BLOCK Ios2 = RTNT_IO_STATUS_BLOCK_INITIALIZER;
            FILE_FS_DEVICE_INFORMATION Info = { 0, 0 };
            NTSTATUS rcNt2 = NtQueryVolumeInformationFile(pThis->hDir, &Ios2, &Info, sizeof(Info), FileFsDeviceInformation);
            if (   !NT_SUCCESS(rcNt2)
                || (Info.Characteristics & FILE_REMOTE_DEVICE)
                || Info.DeviceType == FILE_DEVICE_NETWORK
                || Info.DeviceType == FILE_DEVICE_NETWORK_FILE_SYSTEM
                || Info.DeviceType == FILE_DEVICE_NETWORK_REDIRECTOR
                || Info.DeviceType == FILE_DEVICE_SMB)
                pThis->cbBufferAlloc = _64K;
        }

        fFirst = false;
        pThis->pabBuffer = (uint8_t *)RTMemAlloc(pThis->cbBufferAlloc);
        if (!pThis->pabBuffer)
        {
            do
            {
                pThis->cbBufferAlloc /= 4;
                pThis->pabBuffer = (uint8_t *)RTMemAlloc(pThis->cbBufferAlloc);
            } while (pThis->pabBuffer == NULL && pThis->cbBufferAlloc > _4K);
            if (!pThis->pabBuffer)
                return VERR_NO_MEMORY;
        }

        /*
         * Also try determining the device number.
         */
        PFILE_FS_VOLUME_INFORMATION pVolInfo = (PFILE_FS_VOLUME_INFORMATION)pThis->pabBuffer;
        pVolInfo->VolumeSerialNumber = 0;
        IO_STATUS_BLOCK Ios = RTNT_IO_STATUS_BLOCK_INITIALIZER;
        NTSTATUS rcNt = NtQueryVolumeInformationFile(pThis->hDir, &Ios,
                                                     pVolInfo, RT_MIN(_2K, pThis->cbBufferAlloc),
                                                     FileFsVolumeInformation);
        if (NT_SUCCESS(rcNt) && NT_SUCCESS(Ios.Status))
            pThis->uDirDev = pVolInfo->VolumeSerialNumber;
        else
            pThis->uDirDev = 0;
        AssertCompile(sizeof(pThis->uDirDev) == sizeof(pVolInfo->VolumeSerialNumber));
        /** @todo Grow RTDEV to 64-bit and add low dword of VolumeCreationTime to the top of uDirDev. */
    }

    /*
     * Read more.
     */
    NTSTATUS rcNt;
    IO_STATUS_BLOCK Ios = RTNT_IO_STATUS_BLOCK_INITIALIZER;
    if (pThis->enmInfoClass != (FILE_INFORMATION_CLASS)0)
    {
#ifdef IPRT_WITH_NT_PATH_PASSTHRU
        if (pThis->enmInfoClass == FileMaximumInformation)
        {
            Ios.Information = 0;
            Ios.Status = rcNt = NtQueryDirectoryObject(pThis->hDir,
                                                       pThis->pabBuffer,
                                                       pThis->cbBufferAlloc,
                                                       RTDIR_NT_SINGLE_RECORD /*ReturnSingleEntry */,
                                                       pThis->fRestartScan,
                                                       &pThis->uObjDirCtx,
                                                       (PULONG)&Ios.Information);
        }
        else
#endif
            rcNt = NtQueryDirectoryFile(pThis->hDir,
                                        NULL /* Event */,
                                        NULL /* ApcRoutine */,
                                        NULL /* ApcContext */,
                                        &Ios,
                                        pThis->pabBuffer,
                                        pThis->cbBufferAlloc,
                                        pThis->enmInfoClass,
                                        RTDIR_NT_SINGLE_RECORD /*ReturnSingleEntry */,
                                        pThis->pNtFilterStr,
                                        pThis->fRestartScan);
    }
    else
    {
        /*
         * The first time around we have to figure which info class we can use
         * as well as the right buffer size.  We prefer an info class which
         * gives us file IDs (Vista+ IIRC) and we prefer large buffers (for long
         * ReFS file names and such), but we'll settle for whatever works...
         *
         * The windows 7 thru 8.1 CIFS servers have been observed to have
         * trouble with large buffers, but weirdly only when listing large
         * directories.  Seems 0x10000 is the max.  (Samba does not exhibit
         * these problems, of course.)
         *
         * This complicates things.  The buffer size issues causes an
         * STATUS_INVALID_PARAMETER error.  Now, you would expect the lack of
         * FileIdBothDirectoryInformation support to return
         * STATUS_INVALID_INFO_CLASS, but I'm not entirely sure if we can 100%
         * depend on third IFSs to get that right.  Nor, am I entirely confident
         * that we can depend on them to check the class before the buffer size.
         *
         * Thus the mess.
         */
        if (RT_MAKE_U64(RTNtCurrentPeb()->OSMinorVersion, RTNtCurrentPeb()->OSMajorVersion) > RT_MAKE_U64(0,5) /* > W2K */)
            pThis->enmInfoClass = FileIdBothDirectoryInformation; /* Introduced in XP, from I can tell. */
        else
            pThis->enmInfoClass = FileBothDirectoryInformation;
        rcNt = NtQueryDirectoryFile(pThis->hDir,
                                    NULL /* Event */,
                                    NULL /* ApcRoutine */,
                                    NULL /* ApcContext */,
                                    &Ios,
                                    pThis->pabBuffer,
                                    pThis->cbBufferAlloc,
                                    pThis->enmInfoClass,
                                    RTDIR_NT_SINGLE_RECORD /*ReturnSingleEntry */,
                                    pThis->pNtFilterStr,
                                    pThis->fRestartScan);
        if (NT_SUCCESS(rcNt))
        { /* likely */ }
        else
        {
            bool fRestartScan = pThis->fRestartScan;
            for (unsigned iRetry = 0; iRetry < 2; iRetry++)
            {
                if (   rcNt == STATUS_INVALID_INFO_CLASS
                    || rcNt == STATUS_INVALID_PARAMETER_8
                    || iRetry != 0)
                    pThis->enmInfoClass = FileBothDirectoryInformation;

                uint32_t cbBuffer = pThis->cbBufferAlloc;
                if (   rcNt == STATUS_INVALID_PARAMETER
                    || rcNt == STATUS_INVALID_PARAMETER_7
                    || rcNt == STATUS_INVALID_NETWORK_RESPONSE
                    || iRetry != 0)
                {
                    cbBuffer = RT_MIN(cbBuffer / 2, _64K);
                    fRestartScan = true;
                }

                for (;;)
                {
                    rcNt = NtQueryDirectoryFile(pThis->hDir,
                                                NULL /* Event */,
                                                NULL /* ApcRoutine */,
                                                NULL /* ApcContext */,
                                                &Ios,
                                                pThis->pabBuffer,
                                                cbBuffer,
                                                pThis->enmInfoClass,
                                                RTDIR_NT_SINGLE_RECORD /*ReturnSingleEntry */,
                                                pThis->pNtFilterStr,
                                                fRestartScan);
                    if (   NT_SUCCESS(rcNt)
                        || cbBuffer == pThis->cbBufferAlloc
                        || cbBuffer <= sizeof(*pThis->uCurData.pBothId) + sizeof(WCHAR) * 260)
                        break;

                    /* Reduce the buffer size agressivly and try again.  We fall back to
                       FindFirstFile values for the final lap.  This means we'll do 4 rounds
                       with the current initial buffer size (64KB, 8KB, 1KB, 0x278/0x268). */
                    cbBuffer /= 8;
                    if (cbBuffer < 1024)
                        cbBuffer = pThis->enmInfoClass == FileIdBothDirectoryInformation
                                 ? sizeof(*pThis->uCurData.pBothId) + sizeof(WCHAR) * 260
                                 : sizeof(*pThis->uCurData.pBoth)   + sizeof(WCHAR) * 260;
                }
                if (NT_SUCCESS(rcNt))
                {
                    pThis->cbBufferAlloc = cbBuffer;
                    break;
                }
            }
        }
    }
    if (!NT_SUCCESS(rcNt))
    {
        /* Note! VBoxSVR and CIFS file systems both ends up with STATUS_NO_SUCH_FILE here instead of STATUS_NO_MORE_FILES. */
        if (rcNt == STATUS_NO_MORE_FILES || rcNt == STATUS_NO_MORE_ENTRIES || rcNt == STATUS_NO_SUCH_FILE)
            return VERR_NO_MORE_FILES;
        return RTErrConvertFromNtStatus(rcNt);
    }
    pThis->fRestartScan = false;
    AssertMsg(  Ios.Information
              > (pThis->enmInfoClass == FileMaximumInformation ? sizeof(*pThis->uCurData.pObjDir) : sizeof(*pThis->uCurData.pBoth)),
              ("Ios.Information=%#x\n", Ios.Information));

    /*
     * Set up the data members.
     */
    pThis->uCurData.u  = (uintptr_t)pThis->pabBuffer;
    pThis->cbBuffer    = Ios.Information;

    int rc = rtDirNtCheckRecord(pThis);
    pThis->fDataUnread = RT_SUCCESS(rc);

    return rc;
}
Ejemplo n.º 9
0
void Mutexplorer::Mutexscanner(WCHAR *pszDir)
{
    HANDLE hObj;
    ULONG ntStatus;
    OBJECT_ATTRIBUTES ObjectAttributes;
    POBJDIR_INFORMATION DirObjInformation;
    UNICODE_STRING UName;
    char szData[1024*2];
    char szBuf[1024*2];
    ULONG dw;
    char szIdentBuf[100];
    ULONG index;
    static int iLevel = 0;

    // set indent of current level

    memset(szIdentBuf, ' ', iLevel * 3);
    szIdentBuf[iLevel * 3] = 0;

    RtlInitUnicodeString(&UName, pszDir);

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

    ntStatus = NtOpenDirectoryObject(
            &hObj,
            STANDARD_RIGHTS_READ |
            DIRECTORY_QUERY,
            &ObjectAttributes);

    if(ntStatus == 0)
    {
        index = 0; // start index

        do
        {
            memset(szData, 0, sizeof(szData));
            DirObjInformation = (POBJDIR_INFORMATION)&szData;
            ntStatus = NtQueryDirectoryObject(
                    hObj,
                    DirObjInformation,
                    sizeof(szData),
                    TRUE,
                    FALSE,
                    &index,
                    &dw);

            if(ntStatus == 0)
            {
                szBuf[0] = 0;

                if (wcscmp(DirObjInformation->ObjectTypeName.Buffer,L"Mutant") == 0)
                {
                    QString mutexName = QString::fromWCharArray(DirObjInformation->ObjectName.Buffer);
                    ui->listWidget->addItem(mutexName);
                }

                if(wcscmp(DirObjInformation->ObjectTypeName.Buffer,
                          L"Directory") == 0)
                {

                    iLevel++;

                    if(wcslen(pszDir) &&
                       pszDir[wcslen(pszDir) - 1] == (WCHAR)'\\')
                    {
                        swprintf((WCHAR*)szBuf, L"%s%wZ", pszDir,
                                 &DirObjInformation->ObjectName);
                    }
                    else
                    {
                        swprintf((WCHAR*)szBuf, L"%s\\%wZ", pszDir,
                                 &DirObjInformation->ObjectName);
                    }

                    Mutexscanner((WCHAR*)szBuf);

                    iLevel--;
                }
            }
            else if(ntStatus == 0)
                printf("NtQueryDirectoryObject = 0x%lX (%S)\n", ntStatus,
                       pszDir);
        }
        while(ntStatus == 0);

        CloseHandle(hObj);
    }
    else
        printf("NtOpenDirectoryObject = 0x%lX (%S)\n", ntStatus,
               pszDir);

}
Ejemplo n.º 10
0
void EnumerateObjects(PWSTR strRoot)
{
	NTSTATUS statusNT;
	HANDLE hDirOb;
	OBJECT_ATTRIBUTES oaAttrib;
	int intCount=0;
	
	HMODULE hNTDLL = LoadLibrary("ntdll.dll");
	NtOpenDirectoryObject = (NTSTATUS (__stdcall *)(HANDLE *, ACCESS_MASK, POBJECT_ATTRIBUTES)) GetProcAddress(hNTDLL,"NtOpenDirectoryObject");
	NtQueryDirectoryObject = (NTSTATUS (__stdcall *)(HANDLE, PVOID, ULONG, BOOLEAN, BOOLEAN, PULONG, PULONG)) GetProcAddress(hNTDLL,"NtQueryDirectoryObject");
	NtQueryDirectoryFile = (NTSTATUS (__stdcall *)(HANDLE, HANDLE, PIO_APC_ROUTINE, PVOID, PIO_STATUS_BLOCK, PVOID, ULONG, FILE_INFORMATION_CLASS, BOOLEAN, PUNICODE_STRING, BOOLEAN)) GetProcAddress(hNTDLL,"NtQueryDirectoryFile");

	oaAttrib.Length = 6*4;
	oaAttrib.RootDirectory = 0;
	oaAttrib.ObjectName = (PUNICODE_STRING)malloc(sizeof(UNICODE_STRING)); /* ObjectName is a UNICODE_STRING of fixed size */
	oaAttrib.Attributes = 0;
	oaAttrib.a = 0;
	oaAttrib.b = 0;

	oaAttrib.ObjectName->Length = (USHORT)wcslen(strRoot)*2;
	oaAttrib.ObjectName->MaximumLength = (USHORT)wcslen(strRoot)*2+2;
	oaAttrib.ObjectName->Buffer = strRoot;

	statusNT = NtOpenDirectoryObject(&hDirOb,DIRECTORY_ALL_ACCESS,&oaAttrib);
	
	if (statusNT != STATUS_SUCCESS)
	{
		return;
	}

	UCHAR *strBuffer = (UCHAR*)malloc(1048576); // lovely
	ULONG uContext=0;
	ULONG uRetlen;
	statusNT = NtQueryDirectoryObject(hDirOb,strBuffer,1048576,false,false,&uContext,&uRetlen);
	UNICODE_STRING *pstrName = (PUNICODE_STRING)strBuffer;

	for(intCount=0;pstrName[intCount].Length != 0;intCount+=2)
	{	
		
		TCHAR strFullpath[MAX_PATH];
		sprintf_s(strFullpath,"\\\\.\\%ws",pstrName[intCount].Buffer);
			
		
		if (wcscmp(pstrName[intCount+1].Buffer,L"Directory") == 0 || wcscmp(pstrName[intCount+1].Buffer,L"SymbolicLink") == 0)
		{
			if (wcsstr(strRoot,pstrName[intCount].Buffer) != NULL) break; 

			TCHAR strNewroot[MAX_PATH];
			_tcscpy_s(strNewroot,strRoot);
			
			if (wcscmp(strRoot,L"\\") != 0) _tcscat_s(strNewroot,L"\\");
			_tcscat_s(strNewroot,pstrName[intCount].Buffer);
			EnumerateObjects(strNewroot);

		}

	}

	CloseHandle(hDirOb);
	if (oaAttrib.ObjectName !=NULL) free(oaAttrib.ObjectName);
	if (strBuffer !=NULL)  free(strBuffer);
}
Ejemplo n.º 11
0
DWORD
ScmGetDriverStatus(PSERVICE lpService,
                   LPSERVICE_STATUS lpServiceStatus)
{
    OBJECT_ATTRIBUTES ObjectAttributes;
    UNICODE_STRING DirName;
    HANDLE DirHandle;
    NTSTATUS Status = STATUS_SUCCESS;
    POBJECT_DIRECTORY_INFORMATION DirInfo;
    ULONG BufferLength;
    ULONG DataLength;
    ULONG Index;
    DWORD dwError = ERROR_SUCCESS;
    BOOLEAN bFound = FALSE;

    DPRINT1("ScmGetDriverStatus() called\n");

    memset(lpServiceStatus, 0, sizeof(SERVICE_STATUS));

    if (lpService->Status.dwServiceType == SERVICE_KERNEL_DRIVER)
    {
        RtlInitUnicodeString(&DirName, L"\\Driver");
    }
    else // if (lpService->Status.dwServiceType == SERVICE_FILE_SYSTEM_DRIVER)
    {
        ASSERT(lpService->Status.dwServiceType == SERVICE_FILE_SYSTEM_DRIVER);
        RtlInitUnicodeString(&DirName, L"\\FileSystem");
    }

    InitializeObjectAttributes(&ObjectAttributes,
                               &DirName,
                               0,
                               NULL,
                               NULL);

    Status = NtOpenDirectoryObject(&DirHandle,
                                   DIRECTORY_QUERY | DIRECTORY_TRAVERSE,
                                   &ObjectAttributes);
    if (!NT_SUCCESS(Status))
    {
        DPRINT1("NtOpenDirectoryObject() failed!\n");
        return RtlNtStatusToDosError(Status);
    }

    BufferLength = sizeof(OBJECT_DIRECTORY_INFORMATION) +
                   2 * MAX_PATH * sizeof(WCHAR);
    DirInfo = (OBJECT_DIRECTORY_INFORMATION*) HeapAlloc(GetProcessHeap(),
                        HEAP_ZERO_MEMORY,
                        BufferLength);

    Index = 0;
    while (TRUE)
    {
        Status = NtQueryDirectoryObject(DirHandle,
                                        DirInfo,
                                        BufferLength,
                                        TRUE,
                                        FALSE,
                                        &Index,
                                        &DataLength);
        if (Status == STATUS_NO_MORE_ENTRIES)
        {
            DPRINT("No more services\n");
            break;
        }

        if (!NT_SUCCESS(Status))
            break;

        DPRINT("Comparing: '%S'  '%wZ'\n", lpService->lpServiceName, &DirInfo->Name);

        if (_wcsicmp(lpService->lpServiceName, DirInfo->Name.Buffer) == 0)
        {
            DPRINT1("Found: '%S'  '%wZ'\n",
                    lpService->lpServiceName, &DirInfo->Name);
            bFound = TRUE;

            break;
        }
    }

    HeapFree(GetProcessHeap(),
             0,
             DirInfo);
    NtClose(DirHandle);

    if (!NT_SUCCESS(Status))
    {
        DPRINT1("Status: %lx\n", Status);
        return RtlNtStatusToDosError(Status);
    }

    if ((bFound == TRUE) &&
        (lpService->Status.dwCurrentState != SERVICE_STOP_PENDING))
    {
        if (lpService->Status.dwCurrentState == SERVICE_STOPPED)
        {
            lpService->Status.dwWin32ExitCode = ERROR_SUCCESS;
            lpService->Status.dwServiceSpecificExitCode = ERROR_SUCCESS;
            lpService->Status.dwCheckPoint = 0;
            lpService->Status.dwWaitHint = 0;
            lpService->Status.dwControlsAccepted = 0;
        }
        else
        {
            lpService->Status.dwCurrentState = SERVICE_RUNNING;
            lpService->Status.dwControlsAccepted = SERVICE_ACCEPT_STOP;

            if (lpService->Status.dwWin32ExitCode == ERROR_SERVICE_NEVER_STARTED)
                lpService->Status.dwWin32ExitCode = ERROR_SUCCESS;
        }
    }
    else
    {
        lpService->Status.dwCurrentState = SERVICE_STOPPED;
        lpService->Status.dwControlsAccepted = 0;
        lpService->Status.dwCheckPoint = 0;
        lpService->Status.dwWaitHint = 0;

        if (lpService->Status.dwCurrentState == SERVICE_STOP_PENDING)
            lpService->Status.dwWin32ExitCode = ERROR_SUCCESS;
        else
            lpService->Status.dwWin32ExitCode = ERROR_GEN_FAILURE;
    }

    if (lpServiceStatus != NULL)
    {
        memcpy(lpServiceStatus,
               &lpService->Status,
               sizeof(SERVICE_STATUS));
    }

    DPRINT1("ScmGetDriverStatus() done (Error: %lu)\n", dwError);

    return ERROR_SUCCESS;
}
Ejemplo n.º 12
0
    HRESULT EnumerateNext(LPITEMIDLIST* ppidl)
    {
        BYTE dirbuffer[2048];
        if (!NT_SUCCESS(NtQueryDirectoryObject(m_directory, dirbuffer, 2048, TRUE, m_first, &m_enumContext, NULL)))
            return S_FALSE;

        m_first = FALSE;

        // if ppidl is NULL, assume the caller was Skip(),
        // so we don't care about the info
        if (!ppidl)
            return S_OK;

        POBJECT_DIRECTORY_INFORMATION info = (POBJECT_DIRECTORY_INFORMATION) dirbuffer;

        if (info->Name.Buffer)
        {
            StringCbCopyNW(m_pend, sizeof(buffer), info->Name.Buffer, info->Name.Length);
        }

        OBJECT_TYPE otype = MapTypeNameToType(info->TypeName.Buffer, info->TypeName.Length);

        DWORD entryBufferLength = FIELD_OFFSET(NtPidlEntry, entryName) + sizeof(WCHAR);
        if (info->Name.Buffer)
            entryBufferLength += info->Name.Length;

        if (otype < 0)
        {
            entryBufferLength += FIELD_OFFSET(NtPidlTypeData, typeName) + sizeof(WCHAR);

            if (info->TypeName.Buffer)
            {
                entryBufferLength += info->TypeName.Length;
            }
        }

        // allocate space for the terminator
        entryBufferLength += FIELD_OFFSET(SHITEMID, abID);

        NtPidlEntry* entry = (NtPidlEntry*) CoTaskMemAlloc(entryBufferLength);
        if (!entry)
            return E_OUTOFMEMORY;

        memset(entry, 0, entryBufferLength);

        entry->cb = FIELD_OFFSET(NtPidlEntry, entryName);
        entry->magic = NT_OBJECT_PIDL_MAGIC;
        entry->objectType = otype;

        if (info->Name.Buffer)
        {
            entry->entryNameLength = info->Name.Length;
            StringCbCopyNW(entry->entryName, entryBufferLength, info->Name.Buffer, info->Name.Length);
            entry->cb += entry->entryNameLength + sizeof(WCHAR);
        }
        else
        {
            entry->entryNameLength = 0;
            entry->entryName[0] = 0;
            entry->cb += sizeof(WCHAR);
        }

        if (otype < 0)
        {
            NtPidlTypeData * typedata = (NtPidlTypeData*) ((PBYTE) entry + entry->cb);
            DWORD remainingSpace = entryBufferLength - ((PBYTE) (typedata->typeName) - (PBYTE) entry);

            if (info->TypeName.Buffer)
            {
                typedata->typeNameLength = info->TypeName.Length;
                StringCbCopyNW(typedata->typeName, remainingSpace, info->TypeName.Buffer, info->TypeName.Length);

                entry->cb += typedata->typeNameLength + sizeof(WCHAR);
            }
            else
            {
                typedata->typeNameLength = 0;
                typedata->typeName[0] = 0;
                entry->cb += typedata->typeNameLength + sizeof(WCHAR);
            }
        }

        *ppidl = (LPITEMIDLIST) entry;

        return S_OK;
    }