Beispiel #1
0
NTSTATUS
SetAdministratorPassword(LPCWSTR Password)
{
    PPOLICY_ACCOUNT_DOMAIN_INFO OrigInfo = NULL;
    PUSER_ACCOUNT_NAME_INFORMATION AccountNameInfo = NULL;
    USER_SET_PASSWORD_INFORMATION PasswordInfo;
    LSA_OBJECT_ATTRIBUTES ObjectAttributes;
    LSA_HANDLE PolicyHandle = NULL;
    SAM_HANDLE ServerHandle = NULL;
    SAM_HANDLE DomainHandle = NULL;
    SAM_HANDLE UserHandle = NULL;
    NTSTATUS Status;

    DPRINT("SYSSETUP: SetAdministratorPassword(%p)\n", Password);

    memset(&ObjectAttributes, 0, sizeof(LSA_OBJECT_ATTRIBUTES));
    ObjectAttributes.Length = sizeof(LSA_OBJECT_ATTRIBUTES);

    Status = LsaOpenPolicy(NULL,
                           &ObjectAttributes,
                           POLICY_VIEW_LOCAL_INFORMATION | POLICY_TRUST_ADMIN,
                           &PolicyHandle);
    if (Status != STATUS_SUCCESS)
    {
        DPRINT1("LsaOpenPolicy() failed (Status: 0x%08lx)\n", Status);
        return Status;
    }

    Status = LsaQueryInformationPolicy(PolicyHandle,
                                       PolicyAccountDomainInformation,
                                       (PVOID *)&OrigInfo);
    if (!NT_SUCCESS(Status))
    {
        DPRINT1("LsaQueryInformationPolicy() failed (Status: 0x%08lx)\n", Status);
        goto done;
    }

    Status = SamConnect(NULL,
                        &ServerHandle,
                        SAM_SERVER_CONNECT | SAM_SERVER_LOOKUP_DOMAIN,
                        NULL);
    if (!NT_SUCCESS(Status))
    {
        DPRINT1("SamConnect() failed (Status: 0x%08lx)\n", Status);
        goto done;
    }

    Status = SamOpenDomain(ServerHandle,
                           DOMAIN_LOOKUP,
                           OrigInfo->DomainSid,
                           &DomainHandle);
    if (!NT_SUCCESS(Status))
    {
        DPRINT1("SamOpenDomain() failed (Status: 0x%08lx)\n", Status);
        goto done;
    }

    Status = SamOpenUser(DomainHandle,
                         USER_FORCE_PASSWORD_CHANGE | USER_READ_GENERAL,
                         DOMAIN_USER_RID_ADMIN,
                         &UserHandle);
    if (!NT_SUCCESS(Status))
    {
        DPRINT1("SamOpenUser() failed (Status %08lx)\n", Status);
        goto done;
    }

    RtlInitUnicodeString(&PasswordInfo.Password, Password);
    PasswordInfo.PasswordExpired = FALSE;

    Status = SamSetInformationUser(UserHandle,
                                   UserSetPasswordInformation,
                                   (PVOID)&PasswordInfo);
    if (!NT_SUCCESS(Status))
    {
        DPRINT1("SamSetInformationUser() failed (Status %08lx)\n", Status);
        goto done;
    }

    Status = SamQueryInformationUser(UserHandle,
                                     UserAccountNameInformation,
                                     (PVOID*)&AccountNameInfo);
    if (!NT_SUCCESS(Status))
    {
        DPRINT1("SamSetInformationUser() failed (Status %08lx)\n", Status);
        goto done;
    }

    AdminInfo.Name = RtlAllocateHeap(RtlGetProcessHeap(),
                                     HEAP_ZERO_MEMORY,
                                     AccountNameInfo->UserName.Length + sizeof(WCHAR));
    if (AdminInfo.Name != NULL)
        RtlCopyMemory(AdminInfo.Name,
                      AccountNameInfo->UserName.Buffer,
                      AccountNameInfo->UserName.Length);

    AdminInfo.Domain = RtlAllocateHeap(RtlGetProcessHeap(),
                                       HEAP_ZERO_MEMORY,
                                       OrigInfo->DomainName.Length + sizeof(WCHAR));
    if (AdminInfo.Domain != NULL)
        RtlCopyMemory(AdminInfo.Domain,
                      OrigInfo->DomainName.Buffer,
                      OrigInfo->DomainName.Length);

    AdminInfo.Password = RtlAllocateHeap(RtlGetProcessHeap(),
                                         0,
                                         (wcslen(Password) + 1) * sizeof(WCHAR));
    if (AdminInfo.Password != NULL)
        wcscpy(AdminInfo.Password, Password);

    DPRINT("Administrator Name: %S\n", AdminInfo.Name);
    DPRINT("Administrator Domain: %S\n", AdminInfo.Domain);
    DPRINT("Administrator Password: %S\n", AdminInfo.Password);

done:
    if (AccountNameInfo != NULL)
        SamFreeMemory(AccountNameInfo);

    if (OrigInfo != NULL)
        LsaFreeMemory(OrigInfo);

    if (PolicyHandle != NULL)
        LsaClose(PolicyHandle);

    if (UserHandle != NULL)
        SamCloseHandle(UserHandle);

    if (DomainHandle != NULL)
        SamCloseHandle(DomainHandle);

    if (ServerHandle != NULL)
        SamCloseHandle(ServerHandle);

    DPRINT1("SYSSETUP: SetAdministratorPassword() done (Status %08lx)\n", Status);

    return Status;
}
Beispiel #2
0
/*
 * @implemented
 */
BOOL
WINAPI
MoveFileWithProgressW (
	LPCWSTR			lpExistingFileName,
	LPCWSTR			lpNewFileName,
	LPPROGRESS_ROUTINE	lpProgressRoutine,
	LPVOID			lpData,
	DWORD			dwFlags
	)
{
	HANDLE hFile = NULL, hNewFile = NULL;
	IO_STATUS_BLOCK IoStatusBlock;
    OBJECT_ATTRIBUTES ObjectAttributes;
	PFILE_RENAME_INFORMATION FileRename;
	NTSTATUS errCode;
	BOOL Result;
	UNICODE_STRING DstPathU;
	BOOL folder = FALSE;

	TRACE("MoveFileWithProgressW()\n");

	if (dwFlags & MOVEFILE_DELAY_UNTIL_REBOOT)
		return add_boot_rename_entry( lpExistingFileName, lpNewFileName, dwFlags );

//    if (dwFlags & MOVEFILE_WRITE_THROUGH)
//        FIXME("MOVEFILE_WRITE_THROUGH unimplemented\n");

    if (!lpNewFileName)
        return DeleteFileW(lpExistingFileName);

    /* validate & translate the filename */
    if (!RtlDosPathNameToNtPathName_U (lpNewFileName,
				           &DstPathU,
				           NULL,
				           NULL))
    {
        WARN("Invalid destination path\n");
        SetLastError(ERROR_PATH_NOT_FOUND);
        return FALSE;
    }

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

    errCode = NtOpenFile( &hNewFile,
                          GENERIC_READ | GENERIC_WRITE | SYNCHRONIZE,
                          &ObjectAttributes,
                          &IoStatusBlock,
                          0,
                          FILE_NON_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT |
                          ((dwFlags & MOVEFILE_WRITE_THROUGH) ? FILE_WRITE_THROUGH : 0) );

    if (NT_SUCCESS(errCode)) /* Destination exists */
    {
        NtClose(hNewFile);

        if (!(dwFlags & MOVEFILE_REPLACE_EXISTING))
        {
			SetLastError(ERROR_ALREADY_EXISTS);
			return FALSE;
	}
	else if (GetFileAttributesW(lpNewFileName) & FILE_ATTRIBUTE_DIRECTORY)
	{
		SetLastError(ERROR_ACCESS_DENIED);
		return FALSE;
	}
    }

	hFile = CreateFileW (lpExistingFileName,
	                     GENERIC_ALL,
	                     FILE_SHARE_WRITE|FILE_SHARE_READ,
	                     NULL,
	                     OPEN_EXISTING,
	                     FILE_FLAG_BACKUP_SEMANTICS |
	                     ((dwFlags & MOVEFILE_WRITE_THROUGH) ? FILE_FLAG_WRITE_THROUGH : 0),
	                     NULL);

	if (hFile == INVALID_HANDLE_VALUE)
	{
	    return FALSE;
	}

	FileRename = RtlAllocateHeap(
		RtlGetProcessHeap(),
		HEAP_ZERO_MEMORY,
		sizeof(FILE_RENAME_INFORMATION) + DstPathU.Length);
	if( !FileRename ) {
		CloseHandle(hFile);
		SetLastError(ERROR_NOT_ENOUGH_MEMORY);
		return FALSE;
	}
	if( dwFlags & MOVEFILE_REPLACE_EXISTING ) {
		FileRename->ReplaceIfExists = TRUE;
	}
	else {
		FileRename->ReplaceIfExists = FALSE;
	}


	memcpy(FileRename->FileName, DstPathU.Buffer, DstPathU.Length);
        RtlFreeHeap (RtlGetProcessHeap (),
		     0,
		     DstPathU.Buffer);

	FileRename->FileNameLength = DstPathU.Length;
	errCode = NtSetInformationFile (hFile,
	                                &IoStatusBlock,
	                                FileRename,
	                                sizeof(FILE_RENAME_INFORMATION) + DstPathU.Length,
	                                FileRenameInformation);
	CloseHandle(hFile);
	RtlFreeHeap(RtlGetProcessHeap(), 0, FileRename);

	if (GetFileAttributesW(lpExistingFileName) & FILE_ATTRIBUTE_DIRECTORY)
	{
           folder = TRUE;
	}

	
	/*
	 *  FIXME:
	 *  Fail now move the folder 
	 *  Before we fail at CreateFileW 
	 */
	 
	 
	if (NT_SUCCESS(errCode))
	{
		Result = TRUE;
	}
	else 
	{
 	        if (folder==FALSE)
		{
		    Result = CopyFileExW (lpExistingFileName,
		                      lpNewFileName,
		                      lpProgressRoutine,
		                      lpData,
		                      NULL,
		                      (dwFlags & MOVEFILE_REPLACE_EXISTING) ? 0 : COPY_FILE_FAIL_IF_EXISTS);
 		    if (Result)
		    {
			/* Cleanup the source file */			
	                Result = DeleteFileW (lpExistingFileName);
		    }
                  }
		 else
		 {
		   /* move folder code start */
		   WIN32_FIND_DATAW findBuffer;
		   LPWSTR lpExistingFileName2 = NULL;
		   LPWSTR lpNewFileName2 = NULL; 
		   LPWSTR lpDeleteFile = NULL;
		   INT size;
		   INT size2;
		   BOOL loop = TRUE;
		   BOOL Result = FALSE;
		   INT max_size = MAX_PATH;


		   		   /* Build the string */
		   size = wcslen(lpExistingFileName); 
		   if (size+6> max_size)
			   max_size = size + 6;

		   lpDeleteFile = (LPWSTR) HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,max_size * sizeof(WCHAR));
		   if (lpDeleteFile == NULL)		   
		       return FALSE;		  		  

		   lpNewFileName2 = (LPWSTR) HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,max_size * sizeof(WCHAR));
		   if (lpNewFileName2 == NULL)
		   {		
		     HeapFree(GetProcessHeap(),0,(VOID *)  lpDeleteFile);
			 return FALSE;
		   }

		   lpExistingFileName2 = (LPWSTR) HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,max_size * sizeof(WCHAR));
		   if (lpExistingFileName2 == NULL)
		   {		
		     HeapFree(GetProcessHeap(),0,(VOID *)  lpNewFileName2);		  	  		    		
		     HeapFree(GetProcessHeap(),0,(VOID *) lpDeleteFile);		
		     return FALSE;
		   }		   		   
		
		   wcscpy( (WCHAR *)lpExistingFileName2,lpExistingFileName);
		   wcscpy( (WCHAR *)&lpExistingFileName2[size],L"\\*.*\0");
	  
		   /* Get the file name */
		   memset(&findBuffer,0,sizeof(WIN32_FIND_DATAW));
		   hFile = FindFirstFileW(lpExistingFileName2,  &findBuffer);
		   if (hFile == INVALID_HANDLE_VALUE) 
		       loop=FALSE;

		   if (findBuffer.cFileName[0] == L'\0')
		       loop=FALSE;
		

		    /* FIXME 
			 * remove readonly flag from source folder and do not set the readonly flag to dest folder 
			 */
		   RemoveReadOnlyAttributeW(lpExistingFileName);
           RemoveReadOnlyAttributeW(lpNewFileName);
		   //CreateDirectoryExW(lpExistingFileName,lpNewFileName,NULL);
		   CreateDirectoryW(lpNewFileName, NULL);
		  		   
		   /* search the files/folders and move them */
		   while (loop==TRUE)
		   {	
		     Result = TRUE;

		     if ((!wcscmp(findBuffer.cFileName,L"..")) || (!wcscmp(findBuffer.cFileName,L".")))
		     {		  
		       loop = FindNextFileW(hFile, &findBuffer);		  
		  		  
		       if (!loop)
		       {					 
		         size = wcslen(lpExistingFileName2)-4;
		         FindClose(hFile);
		         hFile = INVALID_HANDLE_VALUE;

		         wcscpy( &lpExistingFileName2[size],L"\0");

		         if (wcsncmp(lpExistingFileName,lpExistingFileName2,size))
		         {  
				   DWORD Attributes;

				   /* delete folder */					  				 
				   TRACE("MoveFileWithProgressW : Delete folder : %S\n",lpDeleteFile);

				   /* remove system folder flag other wise we can not delete the folder */
				   Attributes = GetFileAttributesW(lpExistingFileName2);
                   if (Attributes != INVALID_FILE_ATTRIBUTES)
                   {	
                     SetFileAttributesW(lpExistingFileName2,(Attributes & ~FILE_ATTRIBUTE_SYSTEM));
				   }
				   
				   RemoveReadOnlyAttributeW(lpExistingFileName2);
					 				   
				   Result = RemoveDirectoryW(lpExistingFileName2);
				   if (Result == FALSE)
				       break;
				 				 
				   loop=TRUE;				 				 
				   size = wcslen(lpExistingFileName); 
				
				   if (size+6>max_size)
				   {				       
		              if (lpNewFileName2 != NULL)		          		
		                  HeapFree(GetProcessHeap(),0,(VOID *)  lpNewFileName2);
		           
		              if (lpExistingFileName2 != NULL)		          	  
		                  HeapFree(GetProcessHeap(),0,(VOID *) lpExistingFileName2);		
		           		   
		              if (lpDeleteFile != NULL)		   		
		                  HeapFree(GetProcessHeap(),0,(VOID *) lpDeleteFile);		
		          
				      return FALSE;
				   }

				   wcscpy( lpExistingFileName2,lpExistingFileName);
				   wcscpy( &lpExistingFileName2[size],L"\\*.*\0");

				   /* Get the file name */
				   memset(&findBuffer,0,sizeof(WIN32_FIND_DATAW));
				   hFile = FindFirstFileW(lpExistingFileName2, &findBuffer);	                 
		         }
               } 		  
               continue;		  		  
             }
	  	  	  
		     if (findBuffer.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
		     {	               

               /* Build the new src string */		  		  		  
               size = wcslen(findBuffer.cFileName); 
               size2= wcslen(lpExistingFileName2);

               if (size2+size+6>max_size)
               {
	              FindClose(hFile);    		 

		         if (lpNewFileName2 != NULL)		          		
		              HeapFree(GetProcessHeap(),0,(VOID *)  lpNewFileName2);
		           
		         if (lpExistingFileName2 != NULL)		          	  
		              HeapFree(GetProcessHeap(),0,(VOID *) lpExistingFileName2);		
		           		   
		         if (lpDeleteFile != NULL)		   		
		              HeapFree(GetProcessHeap(),0,(VOID *) lpDeleteFile);		
		          
				 return FALSE;			      				 
	           }

	            wcscpy( &lpExistingFileName2[size2-3],findBuffer.cFileName);			   			  
                wcscpy( &lpExistingFileName2[size2+size-3],L"\0");
			   

			   /* Continue */
			   wcscpy( lpDeleteFile,lpExistingFileName2);
	           wcscpy( &lpExistingFileName2[size2+size-3],L"\\*.*\0");
          
		  
	           /* Build the new dst string */
	           size = wcslen(lpExistingFileName2) + wcslen(lpNewFileName);
	           size2 = wcslen(lpExistingFileName);
		  
	           if (size>max_size)
	           {
	             FindClose(hFile);    		 

		         if (lpNewFileName2 != NULL)		          		
		              HeapFree(GetProcessHeap(),0,(VOID *)  lpNewFileName2);
		           
		         if (lpExistingFileName2 != NULL)		          	  
		              HeapFree(GetProcessHeap(),0,(VOID *) lpExistingFileName2);		
		           		   
		         if (lpDeleteFile != NULL)		   		
		              HeapFree(GetProcessHeap(),0,(VOID *) lpDeleteFile);		
		          
				 return FALSE;			     
	           }

	           wcscpy( lpNewFileName2,lpNewFileName);		 		  
	           size = wcslen(lpNewFileName);		 
	           wcscpy( &lpNewFileName2[size], &lpExistingFileName2[size2]);
	           size = wcslen(lpNewFileName2);
	           wcscpy( &lpNewFileName2[size-4],L"\0");
	           
	           /* Create Folder */	          

			   /* FIXME 
			    * remove readonly flag from source folder and do not set the readonly flag to dest folder 
				*/
			   RemoveReadOnlyAttributeW(lpDeleteFile);
			   RemoveReadOnlyAttributeW(lpNewFileName2);

			   CreateDirectoryW(lpNewFileName2,NULL);
	           //CreateDirectoryExW(lpDeleteFile, lpNewFileName2,NULL);
			   

			   /* set new search path  from src string */
	           FindClose(hFile);
	           memset(&findBuffer,0,sizeof(WIN32_FIND_DATAW));
	           hFile = FindFirstFileW(lpExistingFileName2, &findBuffer);
	         }
		     else
		     {
		  
	           /* Build the new string */		  		  		  		  
	           size = wcslen(findBuffer.cFileName); 
	           size2= wcslen(lpExistingFileName2);
	           wcscpy( lpDeleteFile,lpExistingFileName2);	   
	           wcscpy( &lpDeleteFile[size2-3],findBuffer.cFileName);	   
		  
	           /* Build dest string */
	           size = wcslen(lpDeleteFile) + wcslen(lpNewFileName);
	           size2 = wcslen(lpExistingFileName);

	           if (size>max_size)
	           {                 				  
			      FindClose(hFile);    		 

		          if (lpNewFileName2 != NULL)		          		
		              HeapFree(GetProcessHeap(),0,(VOID *)  lpNewFileName2);
		           
		          if (lpExistingFileName2 != NULL)		          	  
		              HeapFree(GetProcessHeap(),0,(VOID *) lpExistingFileName2);		
		           		   
		          if (lpDeleteFile != NULL)		   		
		              HeapFree(GetProcessHeap(),0,(VOID *) lpDeleteFile);		
		          
				  return FALSE;
			   }
		  
               wcscpy( lpNewFileName2,lpNewFileName);		 		  
               size = wcslen(lpNewFileName);		 
               wcscpy(&lpNewFileName2[size],&lpDeleteFile[size2]);
		 
              
			   /* overrite existsen file, if the file got the flag have readonly 
			    * we need reomve that flag 
				*/
			   
			    /* copy file */
			   
			   TRACE("MoveFileWithProgressW : Copy file : %S to %S\n",lpDeleteFile, lpNewFileName2);
			   RemoveReadOnlyAttributeW(lpDeleteFile);
			   RemoveReadOnlyAttributeW(lpNewFileName2);
			  
			   Result = CopyFileExW (lpDeleteFile,
		                      lpNewFileName2,
		                      lpProgressRoutine,
		                      lpData,
		                      NULL,
		                      0);

			   if (Result == FALSE)                                
                   break;
              
               /* delete file */               		            
			   TRACE("MoveFileWithProgressW : remove readonly flag from file : %S\n",lpNewFileName2);
			   Result = RemoveReadOnlyAttributeW(lpDeleteFile);
			   if (Result == FALSE)
			       break;

               TRACE("MoveFileWithProgressW : Delete file : %S\n",lpDeleteFile);
			   Result = DeleteFileW(lpDeleteFile);
               if (Result == FALSE)                               
                   break;
              
             }	  	              
             loop = FindNextFileW(hFile, &findBuffer);	  	  
           }

           
		   /* Remove last folder */
           if ((loop == FALSE) && (Result != FALSE))
		   {
		     DWORD Attributes;

			 Attributes = GetFileAttributesW(lpDeleteFile);
             if (Attributes != INVALID_FILE_ATTRIBUTES)
             {	
                SetFileAttributesW(lpDeleteFile,(Attributes & ~FILE_ATTRIBUTE_SYSTEM));
			 }
					 				   				 
		     Result = RemoveDirectoryW(lpExistingFileName);		     
		   }
           
		   /* Cleanup */
		   FindClose(hFile);    
		   
		   if (lpNewFileName2 != NULL)
		   {		
		     HeapFree(GetProcessHeap(),0,(VOID *)  lpNewFileName2);
		     lpNewFileName2 = NULL;
		   }

		   if (lpExistingFileName2 != NULL)
		   {	  
		     HeapFree(GetProcessHeap(),0,(VOID *) lpExistingFileName2);		
		     lpExistingFileName2 = NULL;
		   }

		   if (lpDeleteFile != NULL)
		   {		
		     HeapFree(GetProcessHeap(),0,(VOID *) lpDeleteFile);		
		     lpDeleteFile = NULL;
		   }

           return Result;

		   // end move folder code		 
		  }
	}
	
	
	return Result;
}
Beispiel #3
0
NTSTATUS
SampRegEnumerateValue(IN HANDLE KeyHandle,
                      IN ULONG Index,
                      OUT LPWSTR Name,
                      IN OUT PULONG NameLength,
                      OUT PULONG Type OPTIONAL,
                      OUT PVOID Data OPTIONAL,
                      IN OUT PULONG DataLength OPTIONAL)
{
    PKEY_VALUE_FULL_INFORMATION ValueInfo = NULL;
    ULONG BufferLength = 0;
    ULONG ReturnedLength;
    NTSTATUS Status;

    TRACE("Index: %lu\n", Index);

    /* Calculate the required buffer length */
    BufferLength = FIELD_OFFSET(KEY_VALUE_FULL_INFORMATION, Name);
    BufferLength += (MAX_PATH + 1) * sizeof(WCHAR);
    if (Data != NULL)
        BufferLength += *DataLength;

    /* Allocate the value buffer */
    ValueInfo = RtlAllocateHeap(RtlGetProcessHeap(), 0, BufferLength);
    if (ValueInfo == NULL)
        return STATUS_NO_MEMORY;

    /* Enumerate the value*/
    Status = ZwEnumerateValueKey(KeyHandle,
                                 Index,
                                 KeyValueFullInformation,
                                 ValueInfo,
                                 BufferLength,
                                 &ReturnedLength);
    if (NT_SUCCESS(Status))
    {
        if (Name != NULL)
        {
            /* Check if the name fits */
            if (ValueInfo->NameLength < (*NameLength * sizeof(WCHAR)))
            {
                /* Copy it */
                RtlMoveMemory(Name,
                              ValueInfo->Name,
                              ValueInfo->NameLength);

                /* Terminate the string */
                Name[ValueInfo->NameLength / sizeof(WCHAR)] = 0;
            }
            else
            {
                /* Otherwise, we ran out of buffer space */
                Status = STATUS_BUFFER_OVERFLOW;
                goto done;
            }
        }

        if (Data != NULL)
        {
            /* Check if the data fits */
            if (ValueInfo->DataLength <= *DataLength)
            {
                /* Copy it */
                RtlMoveMemory(Data,
                              (PVOID)((ULONG_PTR)ValueInfo + ValueInfo->DataOffset),
                              ValueInfo->DataLength);

                /* if the type is REG_SZ and data is not 0-terminated
                 * and there is enough space in the buffer NT appends a \0 */
                if (IsStringType(ValueInfo->Type) &&
                    ValueInfo->DataLength <= *DataLength - sizeof(WCHAR))
                {
                    WCHAR *ptr = (WCHAR *)((ULONG_PTR)Data + ValueInfo->DataLength);
                    if ((ptr > (WCHAR *)Data) && ptr[-1])
                        *ptr = 0;
                }
            }
            else
            {
                Status = STATUS_BUFFER_OVERFLOW;
                goto done;
            }
        }
    }

done:
    if ((NT_SUCCESS(Status)) || (Status == STATUS_BUFFER_OVERFLOW))
    {
        if (Type != NULL)
            *Type = ValueInfo->Type;

        if (NameLength != NULL)
            *NameLength = ValueInfo->NameLength;

        if (DataLength != NULL)
            *DataLength = ValueInfo->DataLength;
    }

    /* Free the buffer and return status */
    if (ValueInfo)
        RtlFreeHeap(RtlGetProcessHeap(), 0, ValueInfo);

    return Status;
}
Beispiel #4
0
static
VOID
ScanForUnpartitionedDiskSpace(
    PDISKENTRY DiskEntry)
{
    ULONGLONG LastStartSector;
    ULONGLONG LastSectorCount;
    ULONGLONG LastUnusedSectorCount;
    PPARTENTRY PartEntry;
    PPARTENTRY NewPartEntry;
    PLIST_ENTRY Entry;

    DPRINT("ScanForUnpartitionedDiskSpace()\n");

    if (IsListEmpty(&DiskEntry->PrimaryPartListHead))
    {
        DPRINT1("No primary partition!\n");

        /* Create a partition table that represents the empty disk */
        NewPartEntry = RtlAllocateHeap(RtlGetProcessHeap(),
                                       HEAP_ZERO_MEMORY,
                                       sizeof(PARTENTRY));
        if (NewPartEntry == NULL)
            return;

        NewPartEntry->DiskEntry = DiskEntry;

        NewPartEntry->IsPartitioned = FALSE;
        NewPartEntry->StartSector.QuadPart = (ULONGLONG)DiskEntry->SectorAlignment;
        NewPartEntry->SectorCount.QuadPart = AlignDown(DiskEntry->SectorCount.QuadPart, DiskEntry->SectorAlignment) -
                                             NewPartEntry->StartSector.QuadPart;

        DPRINT1("First Sector: %I64u\n", NewPartEntry->StartSector.QuadPart);
        DPRINT1("Last Sector: %I64u\n", NewPartEntry->StartSector.QuadPart + NewPartEntry->SectorCount.QuadPart - 1);
        DPRINT1("Total Sectors: %I64u\n", NewPartEntry->SectorCount.QuadPart);

        NewPartEntry->FormatState = Unformatted;

        InsertTailList(&DiskEntry->PrimaryPartListHead,
                       &NewPartEntry->ListEntry);

        return;
    }

    /* Start partition at head 1, cylinder 0 */
    LastStartSector = DiskEntry->SectorAlignment;
    LastSectorCount = 0ULL;
    LastUnusedSectorCount = 0ULL;

    Entry = DiskEntry->PrimaryPartListHead.Flink;
    while (Entry != &DiskEntry->PrimaryPartListHead)
    {
        PartEntry = CONTAINING_RECORD(Entry, PARTENTRY, ListEntry);

        if (PartEntry->PartitionType != PARTITION_ENTRY_UNUSED ||
            PartEntry->SectorCount.QuadPart != 0ULL)
        {
            LastUnusedSectorCount =
                PartEntry->StartSector.QuadPart - (LastStartSector + LastSectorCount);

            if (PartEntry->StartSector.QuadPart > (LastStartSector + LastSectorCount) &&
                LastUnusedSectorCount >= (ULONGLONG)DiskEntry->SectorAlignment)
            {
                DPRINT("Unpartitioned disk space %I64u sectors\n", LastUnusedSectorCount);

                NewPartEntry = RtlAllocateHeap(RtlGetProcessHeap(),
                                               HEAP_ZERO_MEMORY,
                                               sizeof(PARTENTRY));
                if (NewPartEntry == NULL)
                    return;

                NewPartEntry->DiskEntry = DiskEntry;

                NewPartEntry->IsPartitioned = FALSE;
                NewPartEntry->StartSector.QuadPart = LastStartSector + LastSectorCount;
                NewPartEntry->SectorCount.QuadPart = AlignDown(NewPartEntry->StartSector.QuadPart + LastUnusedSectorCount, DiskEntry->SectorAlignment) -
                                                     NewPartEntry->StartSector.QuadPart;

                DPRINT1("First Sector: %I64u\n", NewPartEntry->StartSector.QuadPart);
                DPRINT1("Last Sector: %I64u\n", NewPartEntry->StartSector.QuadPart + NewPartEntry->SectorCount.QuadPart - 1);
                DPRINT1("Total Sectors: %I64u\n", NewPartEntry->SectorCount.QuadPart);

                NewPartEntry->FormatState = Unformatted;

                /* Insert the table into the list */
                InsertTailList(&PartEntry->ListEntry,
                               &NewPartEntry->ListEntry);
            }

            LastStartSector = PartEntry->StartSector.QuadPart;
            LastSectorCount = PartEntry->SectorCount.QuadPart;
        }

        Entry = Entry->Flink;
    }

    /* Check for trailing unpartitioned disk space */
    if ((LastStartSector + LastSectorCount) < DiskEntry->SectorCount.QuadPart)
    {
        LastUnusedSectorCount = AlignDown(DiskEntry->SectorCount.QuadPart - (LastStartSector + LastSectorCount), DiskEntry->SectorAlignment);

        if (LastUnusedSectorCount >= (ULONGLONG)DiskEntry->SectorAlignment)
        {
            DPRINT1("Unpartitioned disk space: %I64u sectors\n", LastUnusedSectorCount);

            NewPartEntry = RtlAllocateHeap(RtlGetProcessHeap(),
                                           HEAP_ZERO_MEMORY,
                                           sizeof(PARTENTRY));
            if (NewPartEntry == NULL)
                return;

            NewPartEntry->DiskEntry = DiskEntry;

            NewPartEntry->IsPartitioned = FALSE;
            NewPartEntry->StartSector.QuadPart = LastStartSector + LastSectorCount;
            NewPartEntry->SectorCount.QuadPart = AlignDown(NewPartEntry->StartSector.QuadPart + LastUnusedSectorCount, DiskEntry->SectorAlignment) -
                                                 NewPartEntry->StartSector.QuadPart;

            DPRINT1("First Sector: %I64u\n", NewPartEntry->StartSector.QuadPart);
            DPRINT1("Last Sector: %I64u\n", NewPartEntry->StartSector.QuadPart + NewPartEntry->SectorCount.QuadPart - 1);
            DPRINT1("Total Sectors: %I64u\n", NewPartEntry->SectorCount.QuadPart);

            NewPartEntry->FormatState = Unformatted;

            /* Append the table to the list */
            InsertTailList(&DiskEntry->PrimaryPartListHead,
                           &NewPartEntry->ListEntry);
        }
    }

    if (DiskEntry->ExtendedPartition != NULL)
    {
        if (IsListEmpty(&DiskEntry->LogicalPartListHead))
        {
            DPRINT1("No logical partition!\n");

            /* Create a partition table entry that represents the empty extended partition */
            NewPartEntry = RtlAllocateHeap(RtlGetProcessHeap(),
                                           HEAP_ZERO_MEMORY,
                                           sizeof(PARTENTRY));
            if (NewPartEntry == NULL)
                return;

            NewPartEntry->DiskEntry = DiskEntry;
            NewPartEntry->LogicalPartition = TRUE;

            NewPartEntry->IsPartitioned = FALSE;
            NewPartEntry->StartSector.QuadPart = DiskEntry->ExtendedPartition->StartSector.QuadPart + (ULONGLONG)DiskEntry->SectorAlignment;
            NewPartEntry->SectorCount.QuadPart = DiskEntry->ExtendedPartition->SectorCount.QuadPart - (ULONGLONG)DiskEntry->SectorAlignment;

            DPRINT1("First Sector: %I64u\n", NewPartEntry->StartSector.QuadPart);
            DPRINT1("Last Sector: %I64u\n", NewPartEntry->StartSector.QuadPart + NewPartEntry->SectorCount.QuadPart - 1);
            DPRINT1("Total Sectors: %I64u\n", NewPartEntry->SectorCount.QuadPart);

            NewPartEntry->FormatState = Unformatted;

            InsertTailList(&DiskEntry->LogicalPartListHead,
                           &NewPartEntry->ListEntry);

            return;
        }

        /* Start partition at head 1, cylinder 0 */
        LastStartSector = DiskEntry->ExtendedPartition->StartSector.QuadPart + (ULONGLONG)DiskEntry->SectorAlignment;
        LastSectorCount = 0ULL;
        LastUnusedSectorCount = 0ULL;

        Entry = DiskEntry->LogicalPartListHead.Flink;
        while (Entry != &DiskEntry->LogicalPartListHead)
        {
            PartEntry = CONTAINING_RECORD(Entry, PARTENTRY, ListEntry);

            if (PartEntry->PartitionType != PARTITION_ENTRY_UNUSED ||
                PartEntry->SectorCount.QuadPart != 0ULL)
            {
                LastUnusedSectorCount =
                    PartEntry->StartSector.QuadPart - (ULONGLONG)DiskEntry->SectorAlignment - (LastStartSector + LastSectorCount);

                if ((PartEntry->StartSector.QuadPart - (ULONGLONG)DiskEntry->SectorAlignment) > (LastStartSector + LastSectorCount) &&
                    LastUnusedSectorCount >= (ULONGLONG)DiskEntry->SectorAlignment)
                {
                    DPRINT("Unpartitioned disk space %I64u sectors\n", LastUnusedSectorCount);

                    NewPartEntry = RtlAllocateHeap(RtlGetProcessHeap(),
                                                   HEAP_ZERO_MEMORY,
                                                   sizeof(PARTENTRY));
                    if (NewPartEntry == NULL)
                        return;

                    NewPartEntry->DiskEntry = DiskEntry;
                    NewPartEntry->LogicalPartition = TRUE;

                    NewPartEntry->IsPartitioned = FALSE;
                    NewPartEntry->StartSector.QuadPart = LastStartSector + LastSectorCount;
                    NewPartEntry->SectorCount.QuadPart = AlignDown(NewPartEntry->StartSector.QuadPart + LastUnusedSectorCount, DiskEntry->SectorAlignment) -
                                                         NewPartEntry->StartSector.QuadPart;

                    DPRINT("First Sector: %I64u\n", NewPartEntry->StartSector.QuadPart);
                    DPRINT("Last Sector: %I64u\n", NewPartEntry->StartSector.QuadPart + NewPartEntry->SectorCount.QuadPart - 1);
                    DPRINT("Total Sectors: %I64u\n", NewPartEntry->SectorCount.QuadPart);

                    NewPartEntry->FormatState = Unformatted;

                    /* Insert the table into the list */
                    InsertTailList(&PartEntry->ListEntry,
                                   &NewPartEntry->ListEntry);
                }

                LastStartSector = PartEntry->StartSector.QuadPart;
                LastSectorCount = PartEntry->SectorCount.QuadPart;
            }

            Entry = Entry->Flink;
        }

        /* Check for trailing unpartitioned disk space */
        if ((LastStartSector + LastSectorCount) < DiskEntry->ExtendedPartition->StartSector.QuadPart + DiskEntry->ExtendedPartition->SectorCount.QuadPart)
        {
            LastUnusedSectorCount = AlignDown(DiskEntry->ExtendedPartition->StartSector.QuadPart + DiskEntry->ExtendedPartition->SectorCount.QuadPart - (LastStartSector + LastSectorCount),
                                              DiskEntry->SectorAlignment);

            if (LastUnusedSectorCount >= (ULONGLONG)DiskEntry->SectorAlignment)
            {
                DPRINT("Unpartitioned disk space: %I64u sectors\n", LastUnusedSectorCount);

                NewPartEntry = RtlAllocateHeap(RtlGetProcessHeap(),
                                               HEAP_ZERO_MEMORY,
                                               sizeof(PARTENTRY));
                if (NewPartEntry == NULL)
                    return;

                NewPartEntry->DiskEntry = DiskEntry;
                NewPartEntry->LogicalPartition = TRUE;

                NewPartEntry->IsPartitioned = FALSE;
                NewPartEntry->StartSector.QuadPart = LastStartSector + LastSectorCount;
                NewPartEntry->SectorCount.QuadPart = AlignDown(NewPartEntry->StartSector.QuadPart + LastUnusedSectorCount, DiskEntry->SectorAlignment) -
                                                     NewPartEntry->StartSector.QuadPart;

                DPRINT("First Sector: %I64u\n", NewPartEntry->StartSector.QuadPart);
                DPRINT("Last Sector: %I64u\n", NewPartEntry->StartSector.QuadPart + NewPartEntry->SectorCount.QuadPart - 1);
                DPRINT("Total Sectors: %I64u\n", NewPartEntry->SectorCount.QuadPart);

                NewPartEntry->FormatState = Unformatted;

                /* Append the table to the list */
                InsertTailList(&DiskEntry->LogicalPartListHead,
                               &NewPartEntry->ListEntry);
            }
        }
    }

    DPRINT("ScanForUnpartitionedDiskSpace() done\n");
}
Beispiel #5
0
/*
 * @implemented
 */
DWORD
WINAPI
QueryDosDeviceA(
    LPCSTR lpDeviceName,
    LPSTR lpTargetPath,
    DWORD ucchMax
    )
{
  UNICODE_STRING DeviceNameU;
  UNICODE_STRING TargetPathU;
  ANSI_STRING TargetPathA;
  DWORD Length;
  DWORD CurrentLength;
  PWCHAR Buffer;

  if (lpDeviceName)
  {
    if (!RtlCreateUnicodeStringFromAsciiz (&DeviceNameU,
					   (LPSTR)lpDeviceName))
    {
      SetLastError (ERROR_NOT_ENOUGH_MEMORY);
      return 0;
    }
  }
  Buffer = RtlAllocateHeap (RtlGetProcessHeap (),
			    0,
			    ucchMax * sizeof(WCHAR));
  if (Buffer == NULL)
  {
    if (lpDeviceName)
    {
      RtlFreeHeap (RtlGetProcessHeap (),
	           0,
	           DeviceNameU.Buffer);
    }
    SetLastError (ERROR_NOT_ENOUGH_MEMORY);
    return 0;
  }

  Length = QueryDosDeviceW (lpDeviceName ? DeviceNameU.Buffer : NULL,
			    Buffer,
			    ucchMax);
  if (Length != 0)
  {
    TargetPathA.Buffer = lpTargetPath;
    TargetPathU.Buffer = Buffer;
    ucchMax = Length;

    while (ucchMax)
    {
      CurrentLength = min (ucchMax, MAXUSHORT / 2);
      TargetPathU.MaximumLength = TargetPathU.Length = (USHORT)CurrentLength * sizeof(WCHAR);
     
      TargetPathA.Length = 0;
      TargetPathA.MaximumLength = (USHORT)CurrentLength;

      RtlUnicodeStringToAnsiString (&TargetPathA,
				    &TargetPathU,
				    FALSE);
      ucchMax -= CurrentLength;
      TargetPathA.Buffer += TargetPathA.Length;
      TargetPathU.Buffer += TargetPathU.Length / sizeof(WCHAR);
    }
  }

  RtlFreeHeap (RtlGetProcessHeap (),
	       0,
	       Buffer);
  if (lpDeviceName)
  {
    RtlFreeHeap (RtlGetProcessHeap (),
	         0,
	         DeviceNameU.Buffer);
  }
  return Length;
}
Beispiel #6
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));
}
Beispiel #7
0
static
VOID
EnumerateBiosDiskEntries(VOID)
{
    RTL_QUERY_REGISTRY_TABLE QueryTable[3];
    WCHAR Name[120];
    ULONG AdapterCount;
    ULONG DiskCount;
    NTSTATUS Status;
    PCM_INT13_DRIVE_PARAMETER Int13Drives;
    PBIOSDISKENTRY BiosDiskEntry;

    memset(QueryTable, 0, sizeof(QueryTable));

    QueryTable[1].Name = L"Configuration Data";
    QueryTable[1].QueryRoutine = SystemConfigurationDataQueryRoutine;
    Int13Drives = NULL;
    Status = RtlQueryRegistryValues(RTL_REGISTRY_ABSOLUTE,
                                    L"\\Registry\\Machine\\HARDWARE\\DESCRIPTION\\System",
                                    &QueryTable[1],
                                    (PVOID)&Int13Drives,
                                    NULL);
    if (!NT_SUCCESS(Status))
    {
        DPRINT1("Unable to query the 'Configuration Data' key in '\\Registry\\Machine\\HARDWARE\\DESCRIPTION\\System', status=%lx\n", Status);
        return;
    }

    AdapterCount = 0;
    while (1)
    {
        swprintf(Name, L"%s\\%lu", ROOT_NAME, AdapterCount);
        Status = RtlQueryRegistryValues(RTL_REGISTRY_ABSOLUTE,
                                        Name,
                                        &QueryTable[2],
                                        NULL,
                                        NULL);
        if (!NT_SUCCESS(Status))
        {
            break;
        }

        swprintf(Name, L"%s\\%lu\\DiskController", ROOT_NAME, AdapterCount);
        Status = RtlQueryRegistryValues(RTL_REGISTRY_ABSOLUTE,
                                        Name,
                                        &QueryTable[2],
                                        NULL,
                                        NULL);
        if (NT_SUCCESS(Status))
        {
            while (1)
            {
                swprintf(Name, L"%s\\%lu\\DiskController\\0", ROOT_NAME, AdapterCount);
                Status = RtlQueryRegistryValues(RTL_REGISTRY_ABSOLUTE,
                                                Name,
                                                &QueryTable[2],
                                                NULL,
                                                NULL);
                if (!NT_SUCCESS(Status))
                {
                    RtlFreeHeap(RtlGetProcessHeap(), 0, Int13Drives);
                    return;
                }

                swprintf(Name, L"%s\\%lu\\DiskController\\0\\DiskPeripheral", ROOT_NAME, AdapterCount);
                Status = RtlQueryRegistryValues(RTL_REGISTRY_ABSOLUTE,
                                                Name,
                                                &QueryTable[2],
                                                NULL,
                                                NULL);
                if (NT_SUCCESS(Status))
                {
                    QueryTable[0].Name = L"Identifier";
                    QueryTable[0].QueryRoutine = DiskIdentifierQueryRoutine;
                    QueryTable[1].Name = L"Configuration Data";
                    QueryTable[1].QueryRoutine = DiskConfigurationDataQueryRoutine;

                    DiskCount = 0;
                    while (1)
                    {
                        BiosDiskEntry = (BIOSDISKENTRY*)RtlAllocateHeap(RtlGetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(BIOSDISKENTRY));
                        if (BiosDiskEntry == NULL)
                        {
                            break;
                        }

                        swprintf(Name, L"%s\\%lu\\DiskController\\0\\DiskPeripheral\\%lu", ROOT_NAME, AdapterCount, DiskCount);
                        Status = RtlQueryRegistryValues(RTL_REGISTRY_ABSOLUTE,
                                                        Name,
                                                        QueryTable,
                                                        (PVOID)BiosDiskEntry,
                                                        NULL);
                        if (!NT_SUCCESS(Status))
                        {
                            RtlFreeHeap(RtlGetProcessHeap(), 0, BiosDiskEntry);
                            break;
                        }

                        BiosDiskEntry->DiskNumber = DiskCount;
                        BiosDiskEntry->Recognized = FALSE;

                        if (DiskCount < Int13Drives[0].NumberDrives)
                        {
                            BiosDiskEntry->Int13DiskData = Int13Drives[DiskCount];
                        }
                        else
                        {
                            DPRINT1("Didn't find int13 drive datas for disk %u\n", DiskCount);
                        }

                        InsertTailList(&BiosDiskListHead, &BiosDiskEntry->ListEntry);

                        DPRINT("DiskNumber:        %lu\n", BiosDiskEntry->DiskNumber);
                        DPRINT("Signature:         %08lx\n", BiosDiskEntry->Signature);
                        DPRINT("Checksum:          %08lx\n", BiosDiskEntry->Checksum);
                        DPRINT("BytesPerSector:    %lu\n", BiosDiskEntry->DiskGeometry.BytesPerSector);
                        DPRINT("NumberOfCylinders: %lu\n", BiosDiskEntry->DiskGeometry.NumberOfCylinders);
                        DPRINT("NumberOfHeads:     %lu\n", BiosDiskEntry->DiskGeometry.NumberOfHeads);
                        DPRINT("DriveSelect:       %02x\n", BiosDiskEntry->Int13DiskData.DriveSelect);
                        DPRINT("MaxCylinders:      %lu\n", BiosDiskEntry->Int13DiskData.MaxCylinders);
                        DPRINT("SectorsPerTrack:   %d\n", BiosDiskEntry->Int13DiskData.SectorsPerTrack);
                        DPRINT("MaxHeads:          %d\n", BiosDiskEntry->Int13DiskData.MaxHeads);
                        DPRINT("NumberDrives:      %d\n", BiosDiskEntry->Int13DiskData.NumberDrives);

                        DiskCount++;
                    }
                }

                RtlFreeHeap(RtlGetProcessHeap(), 0, Int13Drives);
                return;
            }
        }

        AdapterCount++;
    }

    RtlFreeHeap(RtlGetProcessHeap(), 0, Int13Drives);
}
Beispiel #8
0
/*
 * @implemented
 */
BOOL
WINAPI
WaitNamedPipeW(LPCWSTR lpNamedPipeName,
               DWORD nTimeOut)
{
    UNICODE_STRING NamedPipeName, NewName, DevicePath, PipePrefix;
    ULONG NameLength;
    ULONG i;
    PWCHAR p;
    ULONG Type;
    OBJECT_ATTRIBUTES ObjectAttributes;
    NTSTATUS Status;
    HANDLE FileHandle;
    IO_STATUS_BLOCK IoStatusBlock;
    ULONG WaitPipeInfoSize;
    PFILE_PIPE_WAIT_FOR_BUFFER WaitPipeInfo;

    /* Start by making a unicode string of the name */
    TRACE("Sent path: %S\n", lpNamedPipeName);
    RtlCreateUnicodeString(&NamedPipeName, lpNamedPipeName);
    NameLength = NamedPipeName.Length / sizeof(WCHAR);

    /* All slashes must become backslashes */
    for (i = 0; i < NameLength; i++)
    {
        /* Check and convert */
        if (NamedPipeName.Buffer[i] == L'/') NamedPipeName.Buffer[i] = L'\\';
    }

    /* Find the path type of the name we were given */
    NewName = NamedPipeName;
    Type = RtlDetermineDosPathNameType_U(lpNamedPipeName);

    /* Check if this was a device path, ie : "\\.\pipe\name" */
    if (Type == RtlPathTypeLocalDevice)
    {
        /* Make sure it's a valid prefix */
        RtlInitUnicodeString(&PipePrefix, L"\\\\.\\pipe\\");
        RtlPrefixString((PANSI_STRING)&PipePrefix, (PANSI_STRING)&NewName, TRUE);

        /* Move past it */
        NewName.Buffer += 9;
        NewName.Length -= 9 * sizeof(WCHAR);

        /* Initialize the Dos Devices name */
        TRACE("NewName: %wZ\n", &NewName);
        RtlInitUnicodeString(&DevicePath, L"\\DosDevices\\pipe\\");
    }
    else if (Type == RtlPathTypeRootLocalDevice)
    {
        /* The path is \\server\\pipe\name; find the pipename itself */
        p = &NewName.Buffer[2];

        /* First loop to get past the server name */
        do
        {
            /* Check if this is a backslash */
            if (*p == L'\\') break;

            /* Check next */
            p++;
        } while (*p);

        /* Now make sure the full name contains "pipe\" */
        if ((*p) && !(_wcsnicmp(p + 1, L"pipe\\", sizeof("pipe\\"))))
        {
            /* Get to the pipe name itself now */
            p += sizeof("pipe\\") - 1;
        }
        else
        {
            /* The name is invalid */
            WARN("Invalid name!\n");
            BaseSetLastNTError(STATUS_OBJECT_PATH_SYNTAX_BAD);
            return FALSE;
        }

        /* FIXME: Open \DosDevices\Unc\Server\Pipe\Name */
    }
    else
    {
        WARN("Invalid path type\n");
        BaseSetLastNTError(STATUS_OBJECT_PATH_SYNTAX_BAD);
        return FALSE;
    }

    /* Now calculate the total length of the structure and allocate it */
    WaitPipeInfoSize = FIELD_OFFSET(FILE_PIPE_WAIT_FOR_BUFFER, Name[0]) +
                       NewName.Length;
    WaitPipeInfo = RtlAllocateHeap(RtlGetProcessHeap(), 0, WaitPipeInfoSize);
    if (WaitPipeInfo == NULL)
    {
        SetLastError(ERROR_NOT_ENOUGH_MEMORY);
        return FALSE;
    }

    /* Initialize the object attributes */
    TRACE("Opening: %wZ\n", &DevicePath);
    InitializeObjectAttributes(&ObjectAttributes,
                               &DevicePath,
                               OBJ_CASE_INSENSITIVE,
                               NULL,
                               NULL);

    /* Open the path */
    Status = NtOpenFile(&FileHandle,
                        FILE_READ_ATTRIBUTES | SYNCHRONIZE,
                        &ObjectAttributes,
                        &IoStatusBlock,
                        FILE_SHARE_READ | FILE_SHARE_WRITE,
                        FILE_SYNCHRONOUS_IO_NONALERT);
    if (!NT_SUCCESS(Status))
    {
        /* Fail; couldn't open */
        WARN("Status: %lx\n", Status);
        BaseSetLastNTError(Status);
        RtlFreeUnicodeString(&NamedPipeName);
        RtlFreeHeap(RtlGetProcessHeap(), 0, WaitPipeInfo);
        return FALSE;
    }

    /* Check what timeout we got */
    if (nTimeOut == NMPWAIT_USE_DEFAULT_WAIT)
    {
        /* Don't use a timeout */
        WaitPipeInfo->TimeoutSpecified = FALSE;
    }
    else
    {
        /* Check if we should wait forever */
        if (nTimeOut == NMPWAIT_WAIT_FOREVER)
        {
            /* Set the max */
            WaitPipeInfo->Timeout.LowPart = 0;
            WaitPipeInfo->Timeout.HighPart = 0x80000000;
        }
        else
        {
            /* Convert to NT format */
            WaitPipeInfo->Timeout.QuadPart = UInt32x32To64(-10000, nTimeOut);
        }

        /* In both cases, we do have a timeout */
        WaitPipeInfo->TimeoutSpecified = TRUE;
    }

    /* Set the length and copy the name */
    WaitPipeInfo->NameLength = NewName.Length;
    RtlCopyMemory(WaitPipeInfo->Name, NewName.Buffer, NewName.Length);

    /* Get rid of the full name */
    RtlFreeUnicodeString(&NamedPipeName);

    /* Let NPFS know of our request */
    Status = NtFsControlFile(FileHandle,
                             NULL,
                             NULL,
                             NULL,
                             &IoStatusBlock,
                             FSCTL_PIPE_WAIT,
                             WaitPipeInfo,
                             WaitPipeInfoSize,
                             NULL,
                             0);

    /* Free our pipe info data and close the handle */
    RtlFreeHeap(RtlGetProcessHeap(), 0, WaitPipeInfo);
    NtClose(FileHandle);

    /* Check the status */
    if (!NT_SUCCESS(Status))
    {
        /* Failure to wait on the pipe */
        WARN("Status: %lx\n", Status);
        BaseSetLastNTError (Status);
        return FALSE;
     }

    /* Success */
    return TRUE;
}
Beispiel #9
0
NTSTATUS
LsapEnumLogonSessions(IN OUT PLSA_API_MSG RequestMsg)
{
    OBJECT_ATTRIBUTES ObjectAttributes;
    HANDLE ProcessHandle = NULL;
    PLIST_ENTRY SessionEntry;
    PLSAP_LOGON_SESSION CurrentSession;
    PLUID SessionList;
    ULONG i, Length, MemSize;
    PVOID ClientBaseAddress = NULL;
    NTSTATUS Status;

    TRACE("LsapEnumLogonSessions(%p)\n", RequestMsg);

    Length = SessionCount * sizeof(LUID);
    SessionList = RtlAllocateHeap(RtlGetProcessHeap(),
                                  HEAP_ZERO_MEMORY,
                                  Length);
    if (SessionList == NULL)
        return STATUS_INSUFFICIENT_RESOURCES;

    i = 0;
    SessionEntry = SessionListHead.Flink;
    while (SessionEntry != &SessionListHead)
    {
        CurrentSession = CONTAINING_RECORD(SessionEntry,
                                           LSAP_LOGON_SESSION,
                                           Entry);

        RtlCopyLuid(&SessionList[i],
                    &CurrentSession->LogonId);

        SessionEntry = SessionEntry->Flink;
        i++;
    }

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

    Status = NtOpenProcess(&ProcessHandle,
                           PROCESS_VM_READ | PROCESS_VM_WRITE | PROCESS_VM_OPERATION,
                           &ObjectAttributes,
                           &RequestMsg->h.ClientId);
    if (!NT_SUCCESS(Status))
    {
        TRACE("NtOpenProcess() failed (Status %lx)\n", Status);
        goto done;
    }

    TRACE("Length: %lu\n", Length);

    MemSize = Length;
    Status = NtAllocateVirtualMemory(ProcessHandle,
                                     &ClientBaseAddress,
                                     0,
                                     &MemSize,
                                     MEM_COMMIT,
                                     PAGE_READWRITE);
    if (!NT_SUCCESS(Status))
    {
        TRACE("NtAllocateVirtualMemory() failed (Status %lx)\n", Status);
        goto done;
    }

    TRACE("MemSize: %lu\n", MemSize);
    TRACE("ClientBaseAddress: %p\n", ClientBaseAddress);

    Status = NtWriteVirtualMemory(ProcessHandle,
                                  ClientBaseAddress,
                                  SessionList,
                                  Length,
                                  NULL);
    if (!NT_SUCCESS(Status))
    {
        TRACE("NtWriteVirtualMemory() failed (Status %lx)\n", Status);
        goto done;
    }

    RequestMsg->EnumLogonSessions.Reply.LogonSessionCount = SessionCount;
    RequestMsg->EnumLogonSessions.Reply.LogonSessionBuffer = ClientBaseAddress;

done:
    if (ProcessHandle != NULL)
        NtClose(ProcessHandle);

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

    return Status;
}
Beispiel #10
0
/*
 * @implemented
 */
BOOL
WINAPI
PeekNamedPipe(HANDLE hNamedPipe,
              LPVOID lpBuffer,
              DWORD nBufferSize,
              LPDWORD lpBytesRead,
              LPDWORD lpTotalBytesAvail,
              LPDWORD lpBytesLeftThisMessage)
{
    PFILE_PIPE_PEEK_BUFFER Buffer;
    IO_STATUS_BLOCK Iosb;
    ULONG BufferSize;
    ULONG BytesRead;
    NTSTATUS Status;

    /* Calculate the buffer space that we'll need and allocate it */
    BufferSize = FIELD_OFFSET(FILE_PIPE_PEEK_BUFFER, Data[nBufferSize]);
    Buffer = RtlAllocateHeap(RtlGetProcessHeap(), 0, BufferSize);
    if (Buffer == NULL)
    {
        SetLastError(ERROR_NOT_ENOUGH_MEMORY);
        return FALSE;
    }

    /* Tell the driver to seek */
    Status = NtFsControlFile(hNamedPipe,
                             NULL,
                             NULL,
                             NULL,
                             &Iosb,
                             FSCTL_PIPE_PEEK,
                             NULL,
                             0,
                             Buffer,
                             BufferSize);
    if (Status == STATUS_PENDING)
    {
        /* Wait for npfs to be done, and update the status */
        Status = NtWaitForSingleObject(hNamedPipe, FALSE, NULL);
        if (NT_SUCCESS(Status))
            Status = Iosb.Status;
    }

    /* Overflow is success for us */
    if (Status == STATUS_BUFFER_OVERFLOW)
        Status = STATUS_SUCCESS;

    /* If we failed */
    if (!NT_SUCCESS(Status))
    {
        /* Free the buffer and return failure */
        RtlFreeHeap(RtlGetProcessHeap(), 0, Buffer);
        BaseSetLastNTError(Status);
        return FALSE;
    }

    /* Check if caller requested bytes available */
    if (lpTotalBytesAvail)
    {
        /* Return bytes available */
        *lpTotalBytesAvail = Buffer->ReadDataAvailable;
    }

    /* Calculate the bytes returned, minus our structure overhead */
    BytesRead = (ULONG)(Iosb.Information -
                        FIELD_OFFSET(FILE_PIPE_PEEK_BUFFER, Data[0]));
    ASSERT(BytesRead <= nBufferSize);

    /* Check if caller requested bytes read */
    if (lpBytesRead)
    {
        /* Return the bytes read */
        *lpBytesRead = BytesRead;
    }

    /* Check if caller requested bytes left */
    if (lpBytesLeftThisMessage)
    {
        /* Calculate total minus what we returned and our structure overhead */
        *lpBytesLeftThisMessage = Buffer->MessageLength - BytesRead;
    }

    /* Check if the caller wanted to see the actual data */
    if (lpBuffer)
    {
        /* Give him what he wants */
        RtlCopyMemory(lpBuffer,
                      Buffer->Data,
                      BytesRead);
    }

    /* Free the buffer */
    RtlFreeHeap(RtlGetProcessHeap(), 0, Buffer);

    return TRUE;
}
Beispiel #11
0
/*
 * @implemented
 */
HANDLE
WINAPI
CreateNamedPipeW(LPCWSTR lpName,
                 DWORD dwOpenMode,
                 DWORD dwPipeMode,
                 DWORD nMaxInstances,
                 DWORD nOutBufferSize,
                 DWORD nInBufferSize,
                 DWORD nDefaultTimeOut,
                 LPSECURITY_ATTRIBUTES lpSecurityAttributes)
{
    UNICODE_STRING NamedPipeName;
    BOOL Result;
    NTSTATUS Status;
    OBJECT_ATTRIBUTES ObjectAttributes;
    HANDLE PipeHandle;
    ACCESS_MASK DesiredAccess;
    ULONG CreateOptions = 0;
    ULONG WriteModeMessage;
    ULONG ReadModeMessage;
    ULONG NonBlocking;
    IO_STATUS_BLOCK Iosb;
    ULONG ShareAccess = 0, Attributes;
    LARGE_INTEGER DefaultTimeOut;
    PSECURITY_DESCRIPTOR SecurityDescriptor = NULL;

    /* Check for valid instances */
    if (nMaxInstances == 0 || nMaxInstances > PIPE_UNLIMITED_INSTANCES)
    {
        /* Fail */
        SetLastError(ERROR_INVALID_PARAMETER);
        return INVALID_HANDLE_VALUE;
    }

    /* Convert to NT syntax */
    if (nMaxInstances == PIPE_UNLIMITED_INSTANCES)
        nMaxInstances = -1;

    /* Convert the name */
    Result = RtlDosPathNameToNtPathName_U(lpName,
                                           &NamedPipeName,
                                           NULL,
                                           NULL);
    if (!Result)
    {
        /* Conversion failed */
        SetLastError(ERROR_PATH_NOT_FOUND);
        return INVALID_HANDLE_VALUE;
    }

    TRACE("Pipe name: %wZ\n", &NamedPipeName);
    TRACE("Pipe name: %S\n", NamedPipeName.Buffer);

    /* Always case insensitive, check if we got extra attributes */
    Attributes = OBJ_CASE_INSENSITIVE;
    if(lpSecurityAttributes)
    {
        /* We did; get the security descriptor */
        SecurityDescriptor = lpSecurityAttributes->lpSecurityDescriptor;

        /* And check if this is pipe's handle will beinheritable */
        if (lpSecurityAttributes->bInheritHandle)
            Attributes |= OBJ_INHERIT;
    }

    /* Now we can initialize the object attributes */
    InitializeObjectAttributes(&ObjectAttributes,
                               &NamedPipeName,
                               Attributes,
                               NULL,
                               SecurityDescriptor);

    /* Setup the default Desired Access */
    DesiredAccess = SYNCHRONIZE | (dwOpenMode & (WRITE_DAC |
                                                 WRITE_OWNER |
                                                 ACCESS_SYSTEM_SECURITY));

    /* Convert to NT Create Flags */
    if (dwOpenMode & FILE_FLAG_WRITE_THROUGH)
    {
        CreateOptions |= FILE_WRITE_THROUGH;
    }

    if (!(dwOpenMode & FILE_FLAG_OVERLAPPED))
    {
        CreateOptions |= FILE_SYNCHRONOUS_IO_NONALERT;
    }

    /* Handle all open modes */
    if (dwOpenMode & PIPE_ACCESS_OUTBOUND)
    {
        ShareAccess |= FILE_SHARE_READ;
        DesiredAccess |= GENERIC_WRITE;
    }

    if (dwOpenMode & PIPE_ACCESS_INBOUND)
    {
        ShareAccess |= FILE_SHARE_WRITE;
        DesiredAccess |= GENERIC_READ;
    }

    /* Handle the type flags */
    if (dwPipeMode & PIPE_TYPE_MESSAGE)
    {
        WriteModeMessage = FILE_PIPE_MESSAGE_TYPE;
    }
    else
    {
        WriteModeMessage = FILE_PIPE_BYTE_STREAM_TYPE;
    }

    /* Handle the mode flags */
    if (dwPipeMode & PIPE_READMODE_MESSAGE)
    {
        ReadModeMessage = FILE_PIPE_MESSAGE_MODE;
    }
    else
    {
        ReadModeMessage = FILE_PIPE_BYTE_STREAM_MODE;
    }

    /* Handle the blocking mode */
    if (dwPipeMode & PIPE_NOWAIT)
    {
        NonBlocking = FILE_PIPE_COMPLETE_OPERATION;
    }
    else
    {
        NonBlocking = FILE_PIPE_QUEUE_OPERATION;
    }

    /* Check if we have a timeout */
    if (nDefaultTimeOut)
    {
        /* Convert the time to NT format */
        DefaultTimeOut.QuadPart = UInt32x32To64(nDefaultTimeOut, -10000);
    }
    else
    {
        /* Use default timeout of 50 ms */
        DefaultTimeOut.QuadPart = -500000;
    }

    /* Now create the pipe */
    Status = NtCreateNamedPipeFile(&PipeHandle,
                                   DesiredAccess,
                                   &ObjectAttributes,
                                   &Iosb,
                                   ShareAccess,
                                   FILE_OPEN_IF,
                                   CreateOptions,
                                   WriteModeMessage,
                                   ReadModeMessage,
                                   NonBlocking,
                                   nMaxInstances,
                                   nInBufferSize,
                                   nOutBufferSize,
                                   &DefaultTimeOut);

    /* Normalize special error codes */
    if ((Status == STATUS_INVALID_DEVICE_REQUEST) ||
        (Status == STATUS_NOT_SUPPORTED))
    {
        Status = STATUS_OBJECT_NAME_INVALID;
    }

    /* Free the name */
    RtlFreeHeap(RtlGetProcessHeap(),
                0,
                NamedPipeName.Buffer);

    /* Check status */
    if (!NT_SUCCESS(Status))
    {
        /* Failed to create it */
        WARN("NtCreateNamedPipe failed (Status %x)!\n", Status);
        BaseSetLastNTError (Status);
        return INVALID_HANDLE_VALUE;
    }

    /* Return the handle */
    return PipeHandle;
}
Beispiel #12
0
/*
 * @implemented
 */
BOOL
WINAPI
DeleteFileW(IN LPCWSTR lpFileName)
{
    FILE_DISPOSITION_INFORMATION FileDispInfo;
    OBJECT_ATTRIBUTES ObjectAttributes;
    IO_STATUS_BLOCK IoStatusBlock;
    UNICODE_STRING NtPathU;
    HANDLE FileHandle;
    NTSTATUS Status;
    RTL_RELATIVE_NAME_U RelativeName;
    PWCHAR PathBuffer;
    FILE_ATTRIBUTE_TAG_INFORMATION FileTagInformation;

    /* Convert to NT path and get the relative name too */
    if (!RtlDosPathNameToNtPathName_U(lpFileName,
                                      &NtPathU,
                                      NULL,
                                      &RelativeName))
    {
        /* Bail out if the path name makes no sense */
        SetLastError(ERROR_PATH_NOT_FOUND);
        return FALSE;
    }

    /* Save the path buffer in case we free it later */
    PathBuffer = NtPathU.Buffer;

    /* If we have a relative name... */
    if (RelativeName.RelativeName.Length)
    {
        /* Do a relative open with only the relative path set */
        NtPathU = RelativeName.RelativeName;
    }
    else
    {
        /* Do a full path open with no containing directory */
        RelativeName.ContainingDirectory = NULL;
    }

    /* Now open the directory name that was passed in */
    InitializeObjectAttributes(&ObjectAttributes,
                               &NtPathU,
                               OBJ_CASE_INSENSITIVE,
                               RelativeName.ContainingDirectory,
                               NULL);
    Status = NtOpenFile(&FileHandle,
                        DELETE | FILE_READ_ATTRIBUTES,
                        &ObjectAttributes,
                        &IoStatusBlock,
                        FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
                        FILE_NON_DIRECTORY_FILE |
                        FILE_OPEN_FOR_BACKUP_INTENT |
                        FILE_OPEN_REPARSE_POINT);
    if (NT_SUCCESS(Status))
    {
        /* Check if there's a reparse point associated with this file handle */
        Status = NtQueryInformationFile(FileHandle,
                                        &IoStatusBlock,
                                        &FileTagInformation,
                                        sizeof(FileTagInformation),
                                        FileAttributeTagInformation);
        if ((NT_SUCCESS(Status)) &&
            (FileTagInformation.FileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) &&
            (FileTagInformation.ReparseTag != IO_REPARSE_TAG_MOUNT_POINT))
        {
            /* There is, so now try to open it with reparse behavior */
            NtClose(FileHandle);
            Status = NtOpenFile(&FileHandle,
                                DELETE,
                                &ObjectAttributes,
                                &IoStatusBlock,
                                FILE_SHARE_DELETE |
                                FILE_SHARE_READ |
                                FILE_SHARE_WRITE,
                                FILE_NON_DIRECTORY_FILE |
                                FILE_OPEN_FOR_BACKUP_INTENT);
            if (!NT_SUCCESS(Status))
            {
                /* We failed -- maybe whoever is handling this tag isn't there */
                if (Status == STATUS_IO_REPARSE_TAG_NOT_HANDLED)
                {
                    /* Try to open it for delete, without reparse behavior */
                    Status = NtOpenFile(&FileHandle,
                                        DELETE,
                                        &ObjectAttributes,
                                        &IoStatusBlock,
                                        FILE_SHARE_READ |
                                        FILE_SHARE_WRITE |
                                        FILE_SHARE_DELETE,
                                        FILE_NON_DIRECTORY_FILE |
                                        FILE_OPEN_FOR_BACKUP_INTENT |
                                        FILE_OPEN_REPARSE_POINT);
                }

                if (!NT_SUCCESS(Status))
                {
                     RtlReleaseRelativeName(&RelativeName);
                     RtlFreeHeap(RtlGetProcessHeap(), 0, PathBuffer);
                     BaseSetLastNTError(Status);
                     return FALSE;
                }
            }
        }
        else if (!(NT_SUCCESS(Status)) &&
                 (Status != STATUS_NOT_IMPLEMENTED) &&
                 (Status != STATUS_INVALID_PARAMETER))
        {
            /* We had some critical error querying the attributes, bail out */
            RtlReleaseRelativeName(&RelativeName);
            RtlFreeHeap(RtlGetProcessHeap(), 0, PathBuffer);
            NtClose(FileHandle);
            BaseSetLastNTError(Status);
            return FALSE;
        }
    }
    else
    {
        /* It's possible that FILE_OPEN_REPARSE_POINT was not understood */
        if (Status == STATUS_INVALID_PARAMETER)
        {
            /* Try opening the file normally, with reparse behavior */
            Status = NtOpenFile(&FileHandle,
                                DELETE,
                                &ObjectAttributes,
                                &IoStatusBlock,
                                FILE_SHARE_DELETE |
                                FILE_SHARE_READ |
                                FILE_SHARE_WRITE,
                                FILE_NON_DIRECTORY_FILE |
                                FILE_OPEN_FOR_BACKUP_INTENT);
            if (!NT_SUCCESS(Status))
            {
                /* This failed too, fail */
                RtlReleaseRelativeName(&RelativeName);
                RtlFreeHeap(RtlGetProcessHeap(), 0, PathBuffer);
                BaseSetLastNTError(Status);
                return FALSE;
            }
        }
        else
        {
            /* Maybe we didn't have READ_ATTRIBUTE rights? */
            if (Status != STATUS_ACCESS_DENIED)
            {
                /* Nope, it was something else, let's fail */
                RtlReleaseRelativeName(&RelativeName);
                RtlFreeHeap(RtlGetProcessHeap(), 0, PathBuffer);
                BaseSetLastNTError(Status);
                return FALSE;
            }

            /* Let's try again, without querying attributes */
            Status = NtOpenFile(&FileHandle,
                                DELETE,
                                &ObjectAttributes,
                                &IoStatusBlock,
                                FILE_SHARE_DELETE |
                                FILE_SHARE_READ |
                                FILE_SHARE_WRITE,
                                FILE_NON_DIRECTORY_FILE |
                                FILE_OPEN_FOR_BACKUP_INTENT |
                                FILE_OPEN_REPARSE_POINT);
            if (!NT_SUCCESS(Status))
            {
                /* This failed too, so bail out */
                RtlReleaseRelativeName(&RelativeName);
                RtlFreeHeap(RtlGetProcessHeap(), 0, PathBuffer);
                BaseSetLastNTError(Status);
                return FALSE;
            }
        }
    }

    /* Ready to delete the file, so cleanup temporary data */
    RtlReleaseRelativeName(&RelativeName);
    RtlFreeHeap(RtlGetProcessHeap(), 0, PathBuffer);

    /* Ask for the file to be deleted */
    FileDispInfo.DeleteFile = TRUE;
    Status = NtSetInformationFile(FileHandle,
                                  &IoStatusBlock,
                                  &FileDispInfo,
                                  sizeof(FILE_DISPOSITION_INFORMATION),
                                  FileDispositionInformation);
    NtClose(FileHandle);
    if (!NT_SUCCESS(Status))
    {
        /* Deletion failed, tell the caller */
        BaseSetLastNTError(Status);
        return FALSE;
    }

    /* Tell the caller deletion worked */
    return TRUE;
}
Beispiel #13
0
/*
 * @implemented
 */
HPEN
APIENTRY
ExtCreatePen(DWORD dwPenStyle,
             DWORD dwWidth,
             CONST LOGBRUSH *lplb,
             DWORD dwStyleCount,
             CONST DWORD *lpStyle)
{
    PVOID lpPackedDIB = NULL;
    HPEN hPen = NULL;
    PBITMAPINFO pConvertedInfo = NULL;
    UINT ConvertedInfoSize = 0, lbStyle;
    BOOL Hit = FALSE;

    if ((dwPenStyle & PS_STYLE_MASK) == PS_USERSTYLE)
    {
        if(!lpStyle)
        {
            SetLastError(ERROR_INVALID_PARAMETER);
            return 0;
        }
    } // This is an enhancement and prevents a call to kernel space.
    else if ((dwPenStyle & PS_STYLE_MASK) == PS_INSIDEFRAME &&
             (dwPenStyle & PS_TYPE_MASK) != PS_GEOMETRIC)
    {
        SetLastError(ERROR_INVALID_PARAMETER);
        return 0;
    }
    else if ((dwPenStyle & PS_STYLE_MASK) == PS_ALTERNATE &&
             (dwPenStyle & PS_TYPE_MASK) != PS_COSMETIC)
    {
        SetLastError(ERROR_INVALID_PARAMETER);
        return 0;
    }
    else
    {
        if (dwStyleCount || lpStyle)
        {
            SetLastError(ERROR_INVALID_PARAMETER);
            return 0;
        }
    }

    lbStyle = lplb->lbStyle;

    if (lplb->lbStyle > BS_HATCHED)
    {
        if (lplb->lbStyle == BS_PATTERN)
        {
            pConvertedInfo = (PBITMAPINFO)lplb->lbHatch;
            if (!pConvertedInfo) return 0;
        }
        else
        {
            if ((lplb->lbStyle == BS_DIBPATTERN) || (lplb->lbStyle == BS_DIBPATTERNPT))
            {
                if (lplb->lbStyle == BS_DIBPATTERN)
                {
                    lbStyle = BS_DIBPATTERNPT;
                    lpPackedDIB = GlobalLock((HGLOBAL)lplb->lbHatch);
                    if (lpPackedDIB == NULL) return 0;
                }
                pConvertedInfo = ConvertBitmapInfo((PBITMAPINFO)lpPackedDIB,
                                                   lplb->lbColor,
                                                   &ConvertedInfoSize,
                                                   TRUE);
                Hit = TRUE; // We converted DIB.
            }
            else
                pConvertedInfo = (PBITMAPINFO)lpStyle;
        }
    }
    else
        pConvertedInfo = (PBITMAPINFO)lplb->lbHatch;


    hPen = NtGdiExtCreatePen(dwPenStyle,
                             dwWidth,
                             lbStyle,
                             lplb->lbColor,
                             lplb->lbHatch,
                             (ULONG_PTR)pConvertedInfo,
                             dwStyleCount,
                             (PULONG)lpStyle,
                             ConvertedInfoSize,
                             FALSE,
                             NULL);


    if (lplb->lbStyle == BS_DIBPATTERN) GlobalUnlock((HGLOBAL)lplb->lbHatch);

    if (Hit)
    {
        if ((PBITMAPINFO)lpPackedDIB != pConvertedInfo)
            RtlFreeHeap(RtlGetProcessHeap(), 0, pConvertedInfo);
    }
    return hPen;
}
Beispiel #14
0
/*++
 * @name CsrServerInitialization
 * @implemented NT4
 *
 * The CsrServerInitialization routine is the native (not Server) entrypoint
 * of this Server DLL. It serves as the entrypoint for CSRSS.
 *
 * @param ArgumentCount
 *        Number of arguments on the command line.
 *
 * @param Arguments
 *        Array of arguments from the command line.
 *
 * @return STATUS_SUCCESS in case of success, STATUS_UNSUCCESSFUL otherwise.
 *
 * @remarks None.
 *
 *--*/
NTSTATUS
NTAPI
CsrServerInitialization(IN ULONG ArgumentCount,
                        IN PCHAR Arguments[])
{
    NTSTATUS Status = STATUS_SUCCESS;

    /* Create the Init Event */
    Status = NtCreateEvent(&CsrInitializationEvent,
                           EVENT_ALL_ACCESS,
                           NULL,
                           SynchronizationEvent,
                           FALSE);
    if (!NT_SUCCESS(Status))
    {
        DPRINT1("CSRSRV:%s: NtCreateEvent failed (Status=%08lx)\n",
                __FUNCTION__, Status);
        return Status;
    }

    /* Cache System Basic Information so we don't always request it */
    Status = NtQuerySystemInformation(SystemBasicInformation,
                                      &CsrNtSysInfo,
                                      sizeof(SYSTEM_BASIC_INFORMATION),
                                      NULL);
    if (!NT_SUCCESS(Status))
    {
        DPRINT1("CSRSRV:%s: NtQuerySystemInformation failed (Status=%08lx)\n",
                __FUNCTION__, Status);
        return Status;
    }

    /* Save our Heap */
    CsrHeap = RtlGetProcessHeap();

    /* Set our Security Descriptor to protect the process */
    Status = CsrSetProcessSecurity();
    if (!NT_SUCCESS(Status))
    {
        DPRINT1("CSRSRV:%s: CsrSetProcessSecurity failed (Status=%08lx)\n",
                __FUNCTION__, Status);
        return Status;
    }

    /* Set up Session Support */
    Status = CsrInitializeNtSessionList();
    if (!NT_SUCCESS(Status))
    {
        DPRINT1("CSRSRV:%s: CsrInitializeSessions failed (Status=%08lx)\n",
                __FUNCTION__, Status);
        return Status;
    }

    /* Set up Process Support and allocate the CSR Root Process */
    Status = CsrInitializeProcessStructure();
    if (!NT_SUCCESS(Status))
    {
        DPRINT1("CSRSRV:%s: CsrInitializeProcessStructure failed (Status=%08lx)\n",
                __FUNCTION__, Status);
        return Status;
    }

    /* Parse the command line */
    Status = CsrParseServerCommandLine(ArgumentCount, Arguments);
    if (!NT_SUCCESS(Status))
    {
        DPRINT1("CSRSRV:%s: CsrParseServerCommandLine failed (Status=%08lx)\n",
                __FUNCTION__, Status);
        return Status;
    }

    /* Finish to initialize the CSR Root Process */
    Status = CsrInitCsrRootProcess();
    if (!NT_SUCCESS(Status))
    {
        DPRINT1("CSRSRV:%s: CsrInitCsrRootProcess failed (Status=%08lx)\n",
                __FUNCTION__, Status);
        return Status;
    }

    /* Now initialize our API Port */
    Status = CsrApiPortInitialize();
    if (!NT_SUCCESS(Status))
    {
        DPRINT1("CSRSRV:%s: CsrApiPortInitialize failed (Status=%08lx)\n",
                __FUNCTION__, Status);
        return Status;
    }

    /* Initialize the API Port for SM communication */
    Status = CsrSbApiPortInitialize();
    if (!NT_SUCCESS(Status))
    {
        DPRINT1("CSRSRV:%s: CsrSbApiPortInitialize failed (Status=%08lx)\n",
                __FUNCTION__, Status);
        return Status;
    }

    /* We're all set! Connect to SM! */
    Status = SmConnectToSm(&CsrSbApiPortName,
                           CsrSbApiPort,
                           IMAGE_SUBSYSTEM_WINDOWS_GUI,
                           &CsrSmApiPort);
    if (!NT_SUCCESS(Status))
    {
        DPRINT1("CSRSRV:%s: SmConnectToSm failed (Status=%08lx)\n",
                __FUNCTION__, Status);
        return Status;
    }

    /* Finito! Signal the event */
    Status = NtSetEvent(CsrInitializationEvent, NULL);
    if (!NT_SUCCESS(Status))
    {
        DPRINT1("CSRSRV:%s: NtSetEvent failed (Status=%08lx)\n",
                __FUNCTION__, Status);
        return Status;
    }

    /* Close the event handle now */
    NtClose(CsrInitializationEvent);

    /* Have us handle Hard Errors */
    Status = NtSetDefaultHardErrorPort(CsrApiPort);
    if (!NT_SUCCESS(Status))
    {
        DPRINT1("CSRSRV:%s: NtSetDefaultHardErrorPort failed (Status=%08lx)\n",
                __FUNCTION__, Status);
        return Status;
    }

    /* Return status */
    return Status;
}
Beispiel #15
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;
        }
}
Beispiel #16
0
NTSTATUS
LsapGetLogonSessionData(IN OUT PLSA_API_MSG RequestMsg)
{
    OBJECT_ATTRIBUTES ObjectAttributes;
    HANDLE ProcessHandle = NULL;
    PLSAP_LOGON_SESSION Session;
    PSECURITY_LOGON_SESSION_DATA LocalSessionData;
    PVOID ClientBaseAddress = NULL;
    ULONG Length, MemSize;
    LPWSTR Ptr;
    NTSTATUS Status;

    TRACE("LsapGetLogonSessionData(%p)\n", RequestMsg);

    TRACE("LogonId: %lx\n", RequestMsg->GetLogonSessionData.Request.LogonId.LowPart);
    Session = LsapGetLogonSession(&RequestMsg->GetLogonSessionData.Request.LogonId);
    if (Session == NULL)
        return STATUS_NO_SUCH_LOGON_SESSION;

    Length = sizeof(SECURITY_LOGON_SESSION_DATA);
/*
             Session->UserName.MaximumLength +
             Session->LogonDomain.MaximumLength +
             Session->AuthenticationPackage.MaximumLength +
             Session->LogonServer.MaximumLength +
             Session->DnsDomainName.MaximumLength +
             Session->Upn.MaximumLength;

    if (Session->Sid != NULL)
        RtlLengthSid(Session->Sid);
*/

    TRACE("Length: %lu\n", Length);

    LocalSessionData = RtlAllocateHeap(RtlGetProcessHeap(),
                                       HEAP_ZERO_MEMORY,
                                       Length);
    if (LocalSessionData == NULL)
        return STATUS_INSUFFICIENT_RESOURCES;

    Ptr = (LPWSTR)((ULONG_PTR)LocalSessionData + sizeof(SECURITY_LOGON_SESSION_DATA));
    TRACE("LocalSessionData: %p  Ptr: %p\n", LocalSessionData, Ptr);

    LocalSessionData->Size = sizeof(SECURITY_LOGON_SESSION_DATA);

    RtlCopyLuid(&LocalSessionData->LogonId,
                &RequestMsg->GetLogonSessionData.Request.LogonId);

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

    Status = NtOpenProcess(&ProcessHandle,
                           PROCESS_VM_READ | PROCESS_VM_WRITE | PROCESS_VM_OPERATION,
                           &ObjectAttributes,
                           &RequestMsg->h.ClientId);
    if (!NT_SUCCESS(Status))
    {
        TRACE("NtOpenProcess() failed (Status %lx)\n", Status);
        goto done;
    }

    MemSize = Length;
    Status = NtAllocateVirtualMemory(ProcessHandle,
                                     &ClientBaseAddress,
                                     0,
                                     &MemSize,
                                     MEM_COMMIT,
                                     PAGE_READWRITE);
    if (!NT_SUCCESS(Status))
    {
        TRACE("NtAllocateVirtualMemory() failed (Status %lx)\n", Status);
        goto done;
    }

    TRACE("MemSize: %lu\n", MemSize);
    TRACE("ClientBaseAddress: %p\n", ClientBaseAddress);

    Status = NtWriteVirtualMemory(ProcessHandle,
                                  ClientBaseAddress,
                                  LocalSessionData,
                                  Length,
                                  NULL);
    if (!NT_SUCCESS(Status))
    {
        TRACE("NtWriteVirtualMemory() failed (Status %lx)\n", Status);
        goto done;
    }

    RequestMsg->GetLogonSessionData.Reply.SessionDataBuffer = ClientBaseAddress;

done:
    if (ProcessHandle != NULL)
        NtClose(ProcessHandle);

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

    return Status;
}
Beispiel #17
0
/*
 * @implemented
 */
LPSTR
WINAPI
GetEnvironmentStringsA (
	VOID
	)
{
	UNICODE_STRING UnicodeString;
	ANSI_STRING AnsiString;
	PWCHAR EnvU;
	PWCHAR PtrU;
	ULONG  Length;
	PCHAR EnvPtr = NULL;

	EnvU = (PWCHAR)(NtCurrentPeb ()->ProcessParameters->Environment);

	if (EnvU == NULL)
		return NULL;

	if (*EnvU == 0)
		return NULL;

	/* get environment size */
	PtrU = EnvU;
	while (*PtrU)
	{
		while (*PtrU)
			PtrU++;
		PtrU++;
	}
	Length = (ULONG)(PtrU - EnvU);
	DPRINT("Length %lu\n", Length);

	/* allocate environment buffer */
	EnvPtr = RtlAllocateHeap (RtlGetProcessHeap (),
	                          0,
	                          Length + 1);
        if (EnvPtr == NULL)
        {
            SetLastError(ERROR_NOT_ENOUGH_MEMORY);
            return NULL;
        }
	DPRINT("EnvPtr %p\n", EnvPtr);

	/* convert unicode environment to ansi */
	UnicodeString.MaximumLength = (USHORT)Length * sizeof(WCHAR) + sizeof(WCHAR);
	UnicodeString.Buffer = EnvU;

	AnsiString.MaximumLength = (USHORT)Length + 1;
	AnsiString.Length = 0;
	AnsiString.Buffer = EnvPtr;

	DPRINT ("UnicodeString.Buffer \'%S\'\n", UnicodeString.Buffer);

	while (*(UnicodeString.Buffer))
	{
		UnicodeString.Length = wcslen (UnicodeString.Buffer) * sizeof(WCHAR);
		UnicodeString.MaximumLength = UnicodeString.Length + sizeof(WCHAR);
		if (UnicodeString.Length > 0)
		{
			AnsiString.Length = 0;
			AnsiString.MaximumLength = (USHORT)Length + 1 - (AnsiString.Buffer - EnvPtr);

			RtlUnicodeStringToAnsiString (&AnsiString,
			                              &UnicodeString,
			                              FALSE);

			AnsiString.Buffer += (AnsiString.Length + 1);
			UnicodeString.Buffer += ((UnicodeString.Length / sizeof(WCHAR)) + 1);
		}
	}
	*(AnsiString.Buffer) = 0;

	return EnvPtr;
}
Beispiel #18
0
NTSTATUS NTAPI
ConDrvWriteConsole(IN PCONSOLE Console,
                   IN PTEXTMODE_SCREEN_BUFFER ScreenBuffer,
                   IN BOOLEAN Unicode,
                   IN PVOID StringBuffer,
                   IN ULONG NumCharsToWrite,
                   OUT PULONG NumCharsWritten OPTIONAL)
{
    NTSTATUS Status = STATUS_SUCCESS;
    PWCHAR Buffer = NULL;
    ULONG Written = 0;
    ULONG Length;

    if (Console == NULL || ScreenBuffer == NULL /* || StringBuffer == NULL */)
        return STATUS_INVALID_PARAMETER;

    /* Validity checks */
    ASSERT(Console == ScreenBuffer->Header.Console);
    ASSERT( (StringBuffer != NULL && NumCharsToWrite >= 0) ||
            (StringBuffer == NULL && NumCharsToWrite == 0) );

    // if (Console->PauseFlags & (PAUSED_FROM_KEYBOARD | PAUSED_FROM_SCROLLBAR | PAUSED_FROM_SELECTION))
    if (Console->PauseFlags && Console->UnpauseEvent != NULL)
    {
        return STATUS_PENDING;
    }

    if (Unicode)
    {
        Buffer = StringBuffer;
    }
    else
    {
        Length = MultiByteToWideChar(Console->OutputCodePage, 0,
                                     (PCHAR)StringBuffer,
                                     NumCharsToWrite,
                                     NULL, 0);
        Buffer = RtlAllocateHeap(RtlGetProcessHeap(), 0, Length * sizeof(WCHAR));
        if (Buffer)
        {
            MultiByteToWideChar(Console->OutputCodePage, 0,
                                (PCHAR)StringBuffer,
                                NumCharsToWrite,
                                (PWCHAR)Buffer, Length);
        }
        else
        {
            Status = STATUS_NO_MEMORY;
        }
    }

    if (Buffer)
    {
        if (NT_SUCCESS(Status))
        {
            Status = ConioWriteConsole(Console,
                                       ScreenBuffer,
                                       Buffer,
                                       NumCharsToWrite,
                                       TRUE);
            if (NT_SUCCESS(Status))
            {
                Written = NumCharsToWrite;
            }
        }

        if (!Unicode) RtlFreeHeap(RtlGetProcessHeap(), 0, Buffer);
    }

    if (NumCharsWritten) *NumCharsWritten = Written;

    return Status;
}
Beispiel #19
0
static BOOLEAN
InitializeFmIfsOnce(void)
{
	OBJECT_ATTRIBUTES ObjectAttributes;
	UNICODE_STRING RegistryPath
		= RTL_CONSTANT_STRING(L"\\REGISTRY\\Machine\\SOFTWARE\\ReactOS\\ReactOS\\CurrentVersion\\IFS");
	HANDLE hKey = NULL;
	PKEY_VALUE_FULL_INFORMATION Buffer;
	ULONG BufferSize = sizeof(KEY_VALUE_FULL_INFORMATION) + MAX_PATH;
	ULONG RequiredSize;
	ULONG i = 0;
	UNICODE_STRING Name;
	UNICODE_STRING Data;
	NTSTATUS Status;

	InitializeListHead(&ProviderListHead);

	/* Read IFS providers from HKLM\SOFTWARE\ReactOS\ReactOS\CurrentVersion\IFS */
	InitializeObjectAttributes(&ObjectAttributes, &RegistryPath, 0, NULL, NULL);
	Status = NtOpenKey(&hKey, KEY_QUERY_VALUE, &ObjectAttributes);
	if (Status == STATUS_OBJECT_NAME_NOT_FOUND)
		return TRUE;
	else if (!NT_SUCCESS(Status))
		return FALSE;

	Buffer = (PKEY_VALUE_FULL_INFORMATION)RtlAllocateHeap(
		RtlGetProcessHeap(),
		0,
		BufferSize);
	if (!Buffer)
	{
		NtClose(hKey);
		return FALSE;
	}

	while (TRUE)
	{
		Status = NtEnumerateValueKey(
			hKey,
			i++,
			KeyValueFullInformation,
			Buffer,
			BufferSize,
			&RequiredSize);
		if (Status == STATUS_BUFFER_OVERFLOW)
			continue;
		else if (!NT_SUCCESS(Status))
			break;
		else if (Buffer->Type != REG_SZ)
			continue;

		Name.Length = Name.MaximumLength = Buffer->NameLength;
		Name.Buffer = Buffer->Name;
		Data.Length = Data.MaximumLength = Buffer->DataLength;
		Data.Buffer = (PWCHAR)((ULONG_PTR)Buffer + Buffer->DataOffset);
		if (Data.Length > sizeof(WCHAR) && Data.Buffer[Data.Length / sizeof(WCHAR) - 1] == UNICODE_NULL)
			Data.Length -= sizeof(WCHAR);

		AddProvider(&Name, Data.Buffer);
	}

	NtClose(hKey);
	RtlFreeHeap(RtlGetProcessHeap(), 0, Buffer);
	return TRUE;
}
Beispiel #20
0
NTSTATUS NTAPI
ConDrvWriteConsoleOutputString(IN PCONSOLE Console,
                               IN PTEXTMODE_SCREEN_BUFFER Buffer,
                               IN CODE_TYPE CodeType,
                               IN PVOID StringBuffer,
                               IN ULONG NumCodesToWrite,
                               IN PCOORD WriteCoord /*,
                               OUT PCOORD EndCoord,
                               OUT PULONG CodesWritten */)
{
    NTSTATUS Status = STATUS_SUCCESS;
    PVOID WriteBuffer = NULL;
    PWCHAR tmpString = NULL;
    DWORD X, Y, Length; // , Written = 0;
    ULONG CodeSize;
    SMALL_RECT UpdateRect;
    PCHAR_INFO Ptr;

    if (Console == NULL || Buffer == NULL ||
        WriteCoord == NULL /* || EndCoord == NULL || CodesWritten == NULL */)
    {
        return STATUS_INVALID_PARAMETER;
    }

    /* Validity checks */
    ASSERT(Console == Buffer->Header.Console);
    ASSERT( (StringBuffer != NULL && NumCodesToWrite >= 0) ||
            (StringBuffer == NULL && NumCodesToWrite == 0) );

    switch (CodeType)
    {
        case CODE_ASCII:
            CodeSize = sizeof(CHAR);
            break;

        case CODE_UNICODE:
            CodeSize = sizeof(WCHAR);
            break;

        case CODE_ATTRIBUTE:
            CodeSize = sizeof(WORD);
            break;

        default:
            return STATUS_INVALID_PARAMETER;
    }

    if (CodeType == CODE_ASCII)
    {
        /* Convert the ASCII string into Unicode before writing it to the console */
        Length = MultiByteToWideChar(Console->OutputCodePage, 0,
                                     (PCHAR)StringBuffer,
                                     NumCodesToWrite,
                                     NULL, 0);
        tmpString = WriteBuffer = RtlAllocateHeap(RtlGetProcessHeap(), 0, Length * sizeof(WCHAR));
        if (WriteBuffer)
        {
            MultiByteToWideChar(Console->OutputCodePage, 0,
                                (PCHAR)StringBuffer,
                                NumCodesToWrite,
                                (PWCHAR)WriteBuffer, Length);
        }
        else
        {
            Status = STATUS_NO_MEMORY;
        }
    }
    else
    {
        /* For CODE_UNICODE or CODE_ATTRIBUTE, we are already OK */
        WriteBuffer = StringBuffer;
    }

    if (WriteBuffer == NULL || !NT_SUCCESS(Status)) goto Cleanup;

    X = WriteCoord->X;
    Y = (WriteCoord->Y + Buffer->VirtualY) % Buffer->ScreenBufferSize.Y;
    Length = NumCodesToWrite;
    // Ptr = ConioCoordToPointer(Buffer, X, Y); // Doesn't work
    // Ptr = &Buffer->Buffer[X + Y * Buffer->ScreenBufferSize.X]; // May work

    while (Length--)
    {
        // Ptr = ConioCoordToPointer(Buffer, X, Y); // Doesn't work either
        Ptr = &Buffer->Buffer[X + Y * Buffer->ScreenBufferSize.X];

        switch (CodeType)
        {
            case CODE_ASCII:
            case CODE_UNICODE:
                Ptr->Char.UnicodeChar = *(PWCHAR)WriteBuffer;
                break;

            case CODE_ATTRIBUTE:
                Ptr->Attributes = *(PWORD)WriteBuffer;
                break;
        }
        WriteBuffer = (PVOID)((ULONG_PTR)WriteBuffer + CodeSize);
        // ++Ptr;

        // Written++;
        if (++X == Buffer->ScreenBufferSize.X)
        {
            X = 0;

            if (++Y == Buffer->ScreenBufferSize.Y)
            {
                Y = 0;
            }
        }
    }

    if ((PCONSOLE_SCREEN_BUFFER)Buffer == Console->ActiveBuffer)
    {
        ConioComputeUpdateRect(Buffer, &UpdateRect, WriteCoord, NumCodesToWrite);
        ConioDrawRegion(Console, &UpdateRect);
    }

    // EndCoord->X = X;
    // EndCoord->Y = (Y + Buffer->ScreenBufferSize.Y - Buffer->VirtualY) % Buffer->ScreenBufferSize.Y;

Cleanup:
    if (tmpString) RtlFreeHeap(RtlGetProcessHeap(), 0, tmpString);

    // CodesWritten = Written;
    return Status;
}
Beispiel #21
0
static
VOID
AddPartitionToDisk(
    ULONG DiskNumber,
    PDISKENTRY DiskEntry,
    ULONG PartitionIndex,
    BOOLEAN LogicalPartition)
{
    PPARTITION_INFORMATION PartitionInfo;
    PPARTENTRY PartEntry;

    PartitionInfo = &DiskEntry->LayoutBuffer->PartitionEntry[PartitionIndex];
    if (PartitionInfo->PartitionType == 0 ||
        (LogicalPartition == TRUE && IsContainerPartition(PartitionInfo->PartitionType)))
        return;

    PartEntry = RtlAllocateHeap(RtlGetProcessHeap(),
                                HEAP_ZERO_MEMORY,
                                sizeof(PARTENTRY));
    if (PartEntry == NULL)
    {
        return;
    }

    PartEntry->DiskEntry = DiskEntry;

    PartEntry->StartSector.QuadPart = (ULONGLONG)PartitionInfo->StartingOffset.QuadPart / DiskEntry->BytesPerSector;
    PartEntry->SectorCount.QuadPart = (ULONGLONG)PartitionInfo->PartitionLength.QuadPart / DiskEntry->BytesPerSector;

    PartEntry->BootIndicator = PartitionInfo->BootIndicator;
    PartEntry->PartitionType = PartitionInfo->PartitionType;
    PartEntry->HiddenSectors = PartitionInfo->HiddenSectors;

    PartEntry->LogicalPartition = LogicalPartition;
    PartEntry->IsPartitioned = TRUE;
    PartEntry->PartitionNumber = PartitionInfo->PartitionNumber;
    PartEntry->PartitionIndex = PartitionIndex;

    if (IsContainerPartition(PartEntry->PartitionType))
    {
        PartEntry->FormatState = Unformatted;

        if (LogicalPartition == FALSE && DiskEntry->ExtendedPartition == NULL)
            DiskEntry->ExtendedPartition = PartEntry;
    }
    else if ((PartEntry->PartitionType == PARTITION_FAT_12) ||
             (PartEntry->PartitionType == PARTITION_FAT_16) ||
             (PartEntry->PartitionType == PARTITION_HUGE) ||
             (PartEntry->PartitionType == PARTITION_XINT13) ||
             (PartEntry->PartitionType == PARTITION_FAT32) ||
             (PartEntry->PartitionType == PARTITION_FAT32_XINT13))
    {
#if 0
        if (CheckFatFormat())
        {
            PartEntry->FormatState = Preformatted;
        }
        else
        {
            PartEntry->FormatState = Unformatted;
        }
#endif
        PartEntry->FormatState = Preformatted;
    }
    else if (PartEntry->PartitionType == PARTITION_EXT2)
    {
#if 0
        if (CheckExt2Format())
        {
            PartEntry->FormatState = Preformatted;
        }
        else
        {
            PartEntry->FormatState = Unformatted;
        }
#endif
        PartEntry->FormatState = Preformatted;
    }
    else if (PartEntry->PartitionType == PARTITION_IFS)
    {
#if 0
        if (CheckNtfsFormat())
        {
            PartEntry->FormatState = Preformatted;
        }
        else if (CheckHpfsFormat())
        {
            PartEntry->FormatState = Preformatted;
        }
        else
        {
            PartEntry->FormatState = Unformatted;
        }
#endif
        PartEntry->FormatState = Preformatted;
    }
    else
    {
        PartEntry->FormatState = UnknownFormat;
    }

    if (LogicalPartition)
        InsertTailList(&DiskEntry->LogicalPartListHead,
                       &PartEntry->ListEntry);
    else
        InsertTailList(&DiskEntry->PrimaryPartListHead,
                       &PartEntry->ListEntry);
}
Beispiel #22
0
NTSTATUS
NTAPI
SmpExecuteCommand(IN PUNICODE_STRING CommandLine,
                  IN ULONG MuSessionId,
                  OUT PHANDLE ProcessId,
                  IN ULONG Flags)
{
    NTSTATUS Status;
    UNICODE_STRING Arguments, Directory, FileName;

    /* There's no longer a debugging subsystem */
    if (Flags & SMP_DEBUG_FLAG) return STATUS_SUCCESS;

    /* Parse the command line to see what execution flags are requested */
    Status = SmpParseCommandLine(CommandLine,
                                 &Flags,
                                 &FileName,
                                 &Directory,
                                 &Arguments);
    if (!NT_SUCCESS(Status))
    {
        /* Fail if we couldn't do that */
        DPRINT1("SMSS: SmpParseCommandLine( %wZ ) failed - Status == %lx\n",
                CommandLine, Status);
        return Status;
    }

    /* Check if autochk is requested */
    if (Flags & SMP_AUTOCHK_FLAG)
    {
        /* Run it */
        Status = SmpInvokeAutoChk(&FileName, &Directory, &Arguments, Flags);
    }
    else if (Flags & SMP_SUBSYSTEM_FLAG)
    {
        Status = SmpLoadSubSystem(&FileName,
                                  &Directory,
                                  CommandLine,
                                  MuSessionId,
                                  ProcessId,
                                  Flags);
    }
    else if (Flags & SMP_INVALID_PATH)
    {
        /* An invalid image was specified, fail */
        DPRINT1("SMSS: Image file (%wZ) not found\n", &FileName);
        Status = STATUS_OBJECT_NAME_NOT_FOUND;
    }
    else
    {
        /* An actual image name was present -- execute it */
        Status = SmpExecuteImage(&FileName,
                                 &Directory,
                                 CommandLine,
                                 MuSessionId,
                                 Flags,
                                 NULL);
    }

    /* Free all the token parameters */
    if (FileName.Buffer) RtlFreeHeap(RtlGetProcessHeap(), 0, FileName.Buffer);
    if (Directory.Buffer) RtlFreeHeap(RtlGetProcessHeap(), 0, Directory.Buffer);
    if (Arguments.Buffer) RtlFreeHeap(RtlGetProcessHeap(), 0, Arguments.Buffer);

    /* Return to the caller */
    if (!NT_SUCCESS(Status))
    {
        DPRINT1("SMSS: Command '%wZ' failed - Status == %x\n",
                CommandLine, Status);
    }
    return Status;
}
Beispiel #23
0
static
VOID
AddDiskToList(
    HANDLE FileHandle,
    ULONG DiskNumber)
{
    DISK_GEOMETRY DiskGeometry;
    SCSI_ADDRESS ScsiAddress;
    PDISKENTRY DiskEntry;
    IO_STATUS_BLOCK Iosb;
    NTSTATUS Status;
    PPARTITION_SECTOR Mbr;
    PULONG Buffer;
    LARGE_INTEGER FileOffset;
    WCHAR Identifier[20];
    ULONG Checksum;
    ULONG Signature;
    ULONG i;
    PLIST_ENTRY ListEntry;
    PBIOSDISKENTRY BiosDiskEntry;
    ULONG LayoutBufferSize;
    PDRIVE_LAYOUT_INFORMATION NewLayoutBuffer;

    Status = NtDeviceIoControlFile(FileHandle,
                                   NULL,
                                   NULL,
                                   NULL,
                                   &Iosb,
                                   IOCTL_DISK_GET_DRIVE_GEOMETRY,
                                   NULL,
                                   0,
                                   &DiskGeometry,
                                   sizeof(DISK_GEOMETRY));
    if (!NT_SUCCESS(Status))
    {
        return;
    }

    if (DiskGeometry.MediaType != FixedMedia &&
        DiskGeometry.MediaType != RemovableMedia)
    {
        return;
    }

    Status = NtDeviceIoControlFile(FileHandle,
                                   NULL,
                                   NULL,
                                   NULL,
                                   &Iosb,
                                   IOCTL_SCSI_GET_ADDRESS,
                                   NULL,
                                   0,
                                   &ScsiAddress,
                                   sizeof(SCSI_ADDRESS));
    if (!NT_SUCCESS(Status))
    {
        return;
    }

    Mbr = (PARTITION_SECTOR*)RtlAllocateHeap(RtlGetProcessHeap(),
                                             0,
                                             DiskGeometry.BytesPerSector);
    if (Mbr == NULL)
    {
        return;
    }

    FileOffset.QuadPart = 0;
    Status = NtReadFile(FileHandle,
                        NULL,
                        NULL,
                        NULL,
                        &Iosb,
                        (PVOID)Mbr,
                        DiskGeometry.BytesPerSector,
                        &FileOffset,
                        NULL);
    if (!NT_SUCCESS(Status))
    {
        RtlFreeHeap(RtlGetProcessHeap(), 0, Mbr);
        DPRINT1("NtReadFile failed, status=%x\n", Status);
        return;
    }
    Signature = Mbr->Signature;

    /* Calculate the MBR checksum */
    Checksum = 0;
    Buffer = (PULONG)Mbr;
    for (i = 0; i < 128; i++)
    {
        Checksum += Buffer[i];
    }
    Checksum = ~Checksum + 1;

    swprintf(Identifier, L"%08x-%08x-A", Checksum, Signature);
    DPRINT("Identifier: %S\n", Identifier);

    DiskEntry = RtlAllocateHeap(RtlGetProcessHeap(),
                                HEAP_ZERO_MEMORY,
                                sizeof(DISKENTRY));
    if (DiskEntry == NULL)
    {
        return;
    }

//    DiskEntry->Checksum = Checksum;
//    DiskEntry->Signature = Signature;
    DiskEntry->BiosFound = FALSE;

    /* Check if this disk has a valid MBR */
    if (Mbr->BootCode[0] == 0 && Mbr->BootCode[1] == 0)
        DiskEntry->NoMbr = TRUE;
    else
        DiskEntry->NoMbr = FALSE;

    /* Free Mbr sector buffer */
    RtlFreeHeap(RtlGetProcessHeap(), 0, Mbr);

    ListEntry = BiosDiskListHead.Flink;
    while (ListEntry != &BiosDiskListHead)
    {
        BiosDiskEntry = CONTAINING_RECORD(ListEntry, BIOSDISKENTRY, ListEntry);
        /* FIXME:
         *   Compare the size from bios and the reported size from driver.
         *   If we have more than one disk with a zero or with the same signatur
         *   we must create new signatures and reboot. After the reboot,
         *   it is possible to identify the disks.
         */
        if (BiosDiskEntry->Signature == Signature &&
            BiosDiskEntry->Checksum == Checksum &&
            !BiosDiskEntry->Recognized)
        {
            if (!DiskEntry->BiosFound)
            {
                DiskEntry->BiosDiskNumber = BiosDiskEntry->DiskNumber;
                DiskEntry->BiosFound = TRUE;
                BiosDiskEntry->Recognized = TRUE;
            }
            else
            {
            }
        }
        ListEntry = ListEntry->Flink;
    }

    if (!DiskEntry->BiosFound)
    {
#if 0
        RtlFreeHeap(ProcessHeap, 0, DiskEntry);
        return;
#else
        DPRINT1("WARNING: Setup could not find a matching BIOS disk entry. Disk %d is not be bootable by the BIOS!\n", DiskNumber);
#endif
    }

    InitializeListHead(&DiskEntry->PrimaryPartListHead);
    InitializeListHead(&DiskEntry->LogicalPartListHead);

    DiskEntry->Cylinders = DiskGeometry.Cylinders.QuadPart;
    DiskEntry->TracksPerCylinder = DiskGeometry.TracksPerCylinder;
    DiskEntry->SectorsPerTrack = DiskGeometry.SectorsPerTrack;
    DiskEntry->BytesPerSector = DiskGeometry.BytesPerSector;

    DPRINT("Cylinders %I64u\n", DiskEntry->Cylinders);
    DPRINT("TracksPerCylinder %I64u\n", DiskEntry->TracksPerCylinder);
    DPRINT("SectorsPerTrack %I64u\n", DiskEntry->SectorsPerTrack);
    DPRINT("BytesPerSector %I64u\n", DiskEntry->BytesPerSector);

    DiskEntry->SectorCount.QuadPart = DiskGeometry.Cylinders.QuadPart *
                                      (ULONGLONG)DiskGeometry.TracksPerCylinder *
                                      (ULONGLONG)DiskGeometry.SectorsPerTrack;

    DiskEntry->SectorAlignment = DiskGeometry.SectorsPerTrack;
    DiskEntry->CylinderAlignment = DiskGeometry.SectorsPerTrack * DiskGeometry.TracksPerCylinder;

    DPRINT1("SectorCount: %I64u\n", DiskEntry->SectorCount);
    DPRINT1("SectorAlignment: %lu\n", DiskEntry->SectorAlignment);
    DPRINT1("CylinderAlignment: %lu\n", DiskEntry->CylinderAlignment);

    DiskEntry->DiskNumber = DiskNumber;
    DiskEntry->Port = ScsiAddress.PortNumber;
    DiskEntry->Bus = ScsiAddress.PathId;
    DiskEntry->Id = ScsiAddress.TargetId;

    GetDriverName(DiskEntry);

    InsertAscendingList(&DiskListHead, DiskEntry, DISKENTRY, ListEntry, DiskNumber);

    /* Allocate a layout buffer with 4 partition entries first */
    LayoutBufferSize = sizeof(DRIVE_LAYOUT_INFORMATION) +
                       ((4 - ANYSIZE_ARRAY) * sizeof(PARTITION_INFORMATION));
    DiskEntry->LayoutBuffer = RtlAllocateHeap(RtlGetProcessHeap(),
                                              HEAP_ZERO_MEMORY,
                                              LayoutBufferSize);
    if (DiskEntry->LayoutBuffer == NULL)
    {
        DPRINT1("Failed to allocate the disk layout buffer!\n");
        return;
    }

    for (;;)
    {
        DPRINT1("Buffer size: %lu\n", LayoutBufferSize);
        Status = NtDeviceIoControlFile(FileHandle,
                                       NULL,
                                       NULL,
                                       NULL,
                                       &Iosb,
                                       IOCTL_DISK_GET_DRIVE_LAYOUT,
                                       NULL,
                                       0,
                                       DiskEntry->LayoutBuffer,
                                       LayoutBufferSize);
        if (NT_SUCCESS(Status))
            break;

        if (Status != STATUS_BUFFER_TOO_SMALL)
        {
            DPRINT1("NtDeviceIoControlFile() failed (Status: 0x%08lx)\n", Status);
            return;
        }

        LayoutBufferSize += 4 * sizeof(PARTITION_INFORMATION);
        NewLayoutBuffer = RtlReAllocateHeap(RtlGetProcessHeap(),
                                            HEAP_ZERO_MEMORY,
                                            DiskEntry->LayoutBuffer,
                                            LayoutBufferSize);
        if (NewLayoutBuffer == NULL)
        {
            DPRINT1("Failed to reallocate the disk layout buffer!\n");
            return;
        }

        DiskEntry->LayoutBuffer = NewLayoutBuffer;
    }

    DPRINT1("PartitionCount: %lu\n", DiskEntry->LayoutBuffer->PartitionCount);

#ifdef DUMP_PARTITION_TABLE
    DumpPartitionTable(DiskEntry);
#endif

    if (DiskEntry->LayoutBuffer->PartitionEntry[0].StartingOffset.QuadPart != 0 &&
        DiskEntry->LayoutBuffer->PartitionEntry[0].PartitionLength.QuadPart != 0 &&
        DiskEntry->LayoutBuffer->PartitionEntry[0].PartitionType != 0)
    {
        if ((DiskEntry->LayoutBuffer->PartitionEntry[0].StartingOffset.QuadPart / DiskEntry->BytesPerSector) % DiskEntry->SectorsPerTrack == 0)
        {
            DPRINT("Use %lu Sector alignment!\n", DiskEntry->SectorsPerTrack);
        }
        else if (DiskEntry->LayoutBuffer->PartitionEntry[0].StartingOffset.QuadPart % (1024 * 1024) == 0)
        {
            DPRINT1("Use megabyte (%lu Sectors) alignment!\n", (1024 * 1024) / DiskEntry->BytesPerSector);
        }
        else
        {
            DPRINT1("No matching alignment found! Partition 1 starts at %I64u\n", DiskEntry->LayoutBuffer->PartitionEntry[0].StartingOffset.QuadPart);
        }
    }
    else
    {
        DPRINT1("No valid partition table found! Use megabyte (%lu Sectors) alignment!\n", (1024 * 1024) / DiskEntry->BytesPerSector);
    }


    if (DiskEntry->LayoutBuffer->PartitionCount == 0)
    {
        DiskEntry->NewDisk = TRUE;
        DiskEntry->LayoutBuffer->PartitionCount = 4;

        for (i = 0; i < 4; i++)
            DiskEntry->LayoutBuffer->PartitionEntry[i].RewritePartition = TRUE;
    }
    else
    {
        for (i = 0; i < 4; i++)
        {
            AddPartitionToDisk(DiskNumber, DiskEntry, i, FALSE);
        }

        for (i = 4; i < DiskEntry->LayoutBuffer->PartitionCount; i += 4)
        {
            AddPartitionToDisk(DiskNumber, DiskEntry, i, TRUE);
        }
    }

    ScanForUnpartitionedDiskSpace(DiskEntry);
}
Beispiel #24
0
NTSTATUS
NTAPI
SmpExecuteInitialCommand(IN ULONG MuSessionId,
                         IN PUNICODE_STRING InitialCommand,
                         IN HANDLE InitialCommandProcess,
                         OUT PHANDLE ReturnPid)
{
    NTSTATUS Status;
    RTL_USER_PROCESS_INFORMATION ProcessInfo;
    UNICODE_STRING Arguments, ImageFileDirectory, ImageFileName;
    ULONG Flags = 0;

    /* Check if we haven't yet connected to ourselves */
    if (!SmApiPort)
    {
        /* Connect to ourselves, as a client */
        Status = SmConnectToSm(0, 0, 0, &SmApiPort);
        if (!NT_SUCCESS(Status))
        {
            DPRINT1("SMSS: Unable to connect to SM - Status == %lx\n", Status);
            return Status;
        }
    }

    /* Parse the initial command line */
    Status = SmpParseCommandLine(InitialCommand,
                                 &Flags,
                                 &ImageFileName,
                                 &ImageFileDirectory,
                                 &Arguments);
    if (Flags & SMP_INVALID_PATH)
    {
        /* Fail if it doesn't exist */
        DPRINT1("SMSS: Initial command image (%wZ) not found\n", &ImageFileName);
        if (ImageFileName.Buffer) RtlFreeHeap(RtlGetProcessHeap(), 0, ImageFileName.Buffer);
        return STATUS_OBJECT_NAME_NOT_FOUND;
    }

    /* And fail if any other reason is also true */
    if (!NT_SUCCESS(Status))
    {
        DPRINT1("SMSS: SmpParseCommandLine( %wZ ) failed - Status == %lx\n",
                InitialCommand, Status);
        return Status;
    }

    /* Execute the initial command -- but defer its full execution */
    Status = SmpExecuteImage(&ImageFileName,
                             &ImageFileDirectory,
                             InitialCommand,
                             MuSessionId,
                             SMP_DEFERRED_FLAG,
                             &ProcessInfo);

    /* Free any buffers we had lying around */
    if (ImageFileName.Buffer)
    {
        RtlFreeHeap(RtlGetProcessHeap(), 0, ImageFileName.Buffer);
    }
    if (ImageFileDirectory.Buffer)
    {
        RtlFreeHeap(RtlGetProcessHeap(), 0, ImageFileDirectory.Buffer);
    }
    if (Arguments.Buffer) RtlFreeHeap(RtlGetProcessHeap(), 0, Arguments.Buffer);

    /* Bail out if we couldn't execute the initial command */
    if (!NT_SUCCESS(Status)) return Status;

    /* Now duplicate the handle to this process */
    Status = NtDuplicateObject(NtCurrentProcess(),
                               ProcessInfo.ProcessHandle,
                               NtCurrentProcess(),
                               InitialCommandProcess,
                               PROCESS_ALL_ACCESS,
                               0,
                               0);
    if (!NT_SUCCESS(Status))
    {
        /* Kill it utterly if duplication failed */
        DPRINT1("SMSS: DupObject Failed. Status == %lx\n", Status);
        NtTerminateProcess(ProcessInfo.ProcessHandle, Status);
        NtResumeThread(ProcessInfo.ThreadHandle, NULL);
        NtClose(ProcessInfo.ThreadHandle);
        NtClose(ProcessInfo.ProcessHandle);
        return Status;
    }

    /* Return PID to the caller, and set this as the initial command PID */
    if (ReturnPid) *ReturnPid = ProcessInfo.ClientId.UniqueProcess;
    if (!MuSessionId) SmpInitialCommandProcessId = ProcessInfo.ClientId.UniqueProcess;

    /* Now call our server execution function to wrap up its initialization */
    Status = SmExecPgm(SmApiPort, &ProcessInfo, FALSE);
    if (!NT_SUCCESS(Status)) DPRINT1("SMSS: SmExecPgm Failed. Status == %lx\n", Status);
    return Status;
}
Beispiel #25
0
/*
 * @implemented
 */
BOOL
WINAPI
DefineDosDeviceW(
    DWORD dwFlags,
    LPCWSTR lpDeviceName,
    LPCWSTR lpTargetPath
    )
{
    ULONG ArgumentCount;
    ULONG BufferSize;
    BASE_API_MESSAGE ApiMessage;
    PBASE_DEFINE_DOS_DEVICE DefineDosDeviceRequest = &ApiMessage.Data.DefineDosDeviceRequest;
    PCSR_CAPTURE_BUFFER CaptureBuffer;
    NTSTATUS Status;
    UNICODE_STRING NtTargetPathU;
    UNICODE_STRING DeviceNameU;
    UNICODE_STRING DeviceUpcaseNameU;
    HANDLE hUser32;
    DEV_BROADCAST_VOLUME dbcv;
    BOOL Result = TRUE;
    DWORD dwRecipients;
    typedef long (WINAPI *BSM_type)(DWORD,LPDWORD,UINT,WPARAM,LPARAM);
    BSM_type BSM_ptr;

    if ( (dwFlags & 0xFFFFFFF0) ||
        ((dwFlags & DDD_EXACT_MATCH_ON_REMOVE) &&
        ! (dwFlags & DDD_REMOVE_DEFINITION)) )
    {
        SetLastError(ERROR_INVALID_PARAMETER);
        return FALSE;
    }

    ArgumentCount = 1;
    BufferSize = 0;
    if (! lpTargetPath)
    {
        RtlInitUnicodeString(&NtTargetPathU,
                             NULL);
    }
    else
    {
        if (dwFlags & DDD_RAW_TARGET_PATH)
        {
            RtlInitUnicodeString(&NtTargetPathU,
                                 lpTargetPath);
        }
        else
        {
            if (! RtlDosPathNameToNtPathName_U(lpTargetPath,
                                               &NtTargetPathU,
                                               0,
                                               0))
            {
                WARN("RtlDosPathNameToNtPathName_U() failed\n");
                BaseSetLastNTError(STATUS_OBJECT_NAME_INVALID);
                return FALSE;
            }
        }
        ArgumentCount = 2;
        BufferSize += NtTargetPathU.Length;
    }

    RtlInitUnicodeString(&DeviceNameU,
                         lpDeviceName);
    RtlUpcaseUnicodeString(&DeviceUpcaseNameU,
                           &DeviceNameU,
                           TRUE);
    BufferSize += DeviceUpcaseNameU.Length;

    CaptureBuffer = CsrAllocateCaptureBuffer(ArgumentCount,
                                             BufferSize);
    if (! CaptureBuffer)
    {
        SetLastError(ERROR_NOT_ENOUGH_MEMORY);
        Result = FALSE;
    }
    else
    {
        DefineDosDeviceRequest->Flags = dwFlags;

        CsrCaptureMessageBuffer(CaptureBuffer,
                                (PVOID)DeviceUpcaseNameU.Buffer,
                                DeviceUpcaseNameU.Length,
                                (PVOID*)&DefineDosDeviceRequest->DeviceName.Buffer);

        DefineDosDeviceRequest->DeviceName.Length =
            DeviceUpcaseNameU.Length;
        DefineDosDeviceRequest->DeviceName.MaximumLength =
            DeviceUpcaseNameU.Length;

        if (NtTargetPathU.Buffer)
        {
            CsrCaptureMessageBuffer(CaptureBuffer,
                                    (PVOID)NtTargetPathU.Buffer,
                                    NtTargetPathU.Length,
                                    (PVOID*)&DefineDosDeviceRequest->TargetPath.Buffer);
        }
        DefineDosDeviceRequest->TargetPath.Length =
            NtTargetPathU.Length;
        DefineDosDeviceRequest->TargetPath.MaximumLength =
            NtTargetPathU.Length;

        Status = CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
                                     CaptureBuffer,
                                     CSR_CREATE_API_NUMBER(BASESRV_SERVERDLL_INDEX, BasepDefineDosDevice),
                                     sizeof(BASE_DEFINE_DOS_DEVICE));
        CsrFreeCaptureBuffer(CaptureBuffer);

        if (!NT_SUCCESS(Status))
        {
            WARN("CsrClientCallServer() failed (Status %lx)\n", Status);
            BaseSetLastNTError(Status);
            Result = FALSE;
        }
        else
        {
            if (! (dwFlags & DDD_NO_BROADCAST_SYSTEM) &&
                DeviceUpcaseNameU.Length == 2 * sizeof(WCHAR) &&
                DeviceUpcaseNameU.Buffer[1] == L':' &&
                ( (DeviceUpcaseNameU.Buffer[0] - L'A') < 26 ))
            {
                hUser32 = LoadLibraryA("user32.dll");
                if (hUser32)
                {
                    BSM_ptr = (BSM_type)
                        GetProcAddress(hUser32, "BroadcastSystemMessageW");
                    if (BSM_ptr)
                    {
                        dwRecipients = BSM_APPLICATIONS;
                        dbcv.dbcv_size = sizeof(DEV_BROADCAST_VOLUME);
                        dbcv.dbcv_devicetype = DBT_DEVTYP_VOLUME;
                        dbcv.dbcv_reserved = 0;
                        dbcv.dbcv_unitmask |= 
                            (1 << (DeviceUpcaseNameU.Buffer[0] - L'A'));
                        dbcv.dbcv_flags = DBTF_NET;
                        (void) BSM_ptr(BSF_SENDNOTIFYMESSAGE | BSF_FLUSHDISK,
                                       &dwRecipients,
                                       WM_DEVICECHANGE,
                                       (WPARAM)DBT_DEVICEARRIVAL,
                                       (LPARAM)&dbcv);
                    }
                    FreeLibrary(hUser32);
                }
            }
        }
    }

    if (NtTargetPathU.Buffer)
    {
        RtlFreeHeap(RtlGetProcessHeap(),
                    0,
                    NtTargetPathU.Buffer);
    }
    RtlFreeUnicodeString(&DeviceUpcaseNameU);
    return Result;
}
Beispiel #26
0
/*
 * @implemented
 */
BOOL WINAPI
CheckTokenMembership(IN HANDLE ExistingTokenHandle,
                     IN PSID SidToCheck,
                     OUT PBOOL IsMember)
{
    PISECURITY_DESCRIPTOR SecurityDescriptor = NULL;
    ACCESS_MASK GrantedAccess;
    struct
    {
        PRIVILEGE_SET PrivilegeSet;
        LUID_AND_ATTRIBUTES Privileges[4];
    } PrivBuffer;
    ULONG PrivBufferSize = sizeof(PrivBuffer);
    GENERIC_MAPPING GenericMapping =
    {
        STANDARD_RIGHTS_READ,
        STANDARD_RIGHTS_WRITE,
        STANDARD_RIGHTS_EXECUTE,
        STANDARD_RIGHTS_ALL
    };
    PACL Dacl;
    ULONG SidLen;
    HANDLE hToken = NULL;
    NTSTATUS Status, AccessStatus;

    /* doesn't return gracefully if IsMember is NULL! */
    *IsMember = FALSE;

    SidLen = RtlLengthSid(SidToCheck);

    if (ExistingTokenHandle == NULL)
    {
        Status = NtOpenThreadToken(NtCurrentThread(),
                                   TOKEN_QUERY,
                                   FALSE,
                                   &hToken);

        if (Status == STATUS_NO_TOKEN)
        {
            /* we're not impersonating, open the primary token */
            Status = NtOpenProcessToken(NtCurrentProcess(),
                                        TOKEN_QUERY | TOKEN_DUPLICATE,
                                        &hToken);
            if (NT_SUCCESS(Status))
            {
                HANDLE hNewToken = FALSE;
                BOOL DupRet;

                /* duplicate the primary token to create an impersonation token */
                DupRet = DuplicateTokenEx(hToken,
                                          TOKEN_QUERY | TOKEN_IMPERSONATE,
                                          NULL,
                                          SecurityImpersonation,
                                          TokenImpersonation,
                                          &hNewToken);

                NtClose(hToken);

                if (!DupRet)
                {
                    WARN("Failed to duplicate the primary token!\n");
                    return FALSE;
                }

                hToken = hNewToken;
            }
        }

        if (!NT_SUCCESS(Status))
        {
            goto Cleanup;
        }
    }
    else
    {
        hToken = ExistingTokenHandle;
    }

    /* create a security descriptor */
    SecurityDescriptor = RtlAllocateHeap(RtlGetProcessHeap(),
                                         0,
                                         sizeof(SECURITY_DESCRIPTOR) +
                                             sizeof(ACL) + SidLen +
                                             sizeof(ACCESS_ALLOWED_ACE));
    if (SecurityDescriptor == NULL)
    {
        Status = STATUS_INSUFFICIENT_RESOURCES;
        goto Cleanup;
    }

    Status = RtlCreateSecurityDescriptor(SecurityDescriptor,
                                         SECURITY_DESCRIPTOR_REVISION);
    if (!NT_SUCCESS(Status))
    {
        goto Cleanup;
    }

    /* set the owner and group */
    Status = RtlSetOwnerSecurityDescriptor(SecurityDescriptor,
                                           SidToCheck,
                                           FALSE);
    if (!NT_SUCCESS(Status))
    {
        goto Cleanup;
    }

    Status = RtlSetGroupSecurityDescriptor(SecurityDescriptor,
                                           SidToCheck,
                                           FALSE);
    if (!NT_SUCCESS(Status))
    {
        goto Cleanup;
    }

    /* create the DACL */
    Dacl = (PACL)(SecurityDescriptor + 1);
    Status = RtlCreateAcl(Dacl,
                          sizeof(ACL) + SidLen + sizeof(ACCESS_ALLOWED_ACE),
                          ACL_REVISION);
    if (!NT_SUCCESS(Status))
    {
        goto Cleanup;
    }

    Status = RtlAddAccessAllowedAce(Dacl,
                                    ACL_REVISION,
                                    0x1,
                                    SidToCheck);
    if (!NT_SUCCESS(Status))
    {
        goto Cleanup;
    }

    /* assign the DACL to the security descriptor */
    Status = RtlSetDaclSecurityDescriptor(SecurityDescriptor,
                                          TRUE,
                                          Dacl,
                                          FALSE);
    if (!NT_SUCCESS(Status))
    {
        goto Cleanup;
    }

    /* it's time to perform the access check. Just use _some_ desired access right
       (same as for the ACE) and see if we're getting it granted. This indicates
       our SID is a member of the token. We however can't use a generic access
       right as those aren't mapped and return an error (STATUS_GENERIC_NOT_MAPPED). */
    Status = NtAccessCheck(SecurityDescriptor,
                           hToken,
                           0x1,
                           &GenericMapping,
                           &PrivBuffer.PrivilegeSet,
                           &PrivBufferSize,
                           &GrantedAccess,
                           &AccessStatus);
    if (NT_SUCCESS(Status) && NT_SUCCESS(AccessStatus) && (GrantedAccess == 0x1))
    {
        *IsMember = TRUE;
    }

Cleanup:
    if (hToken != NULL && hToken != ExistingTokenHandle)
    {
        NtClose(hToken);
    }

    if (SecurityDescriptor != NULL)
    {
        RtlFreeHeap(RtlGetProcessHeap(),
                    0,
                    SecurityDescriptor);
    }

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

    return TRUE;
}
Beispiel #27
0
/***********************************************************************
 *           add_boot_rename_entry
 *
 * Adds an entry to the registry that is loaded when windows boots and
 * checks if there are some files to be removed or renamed/moved.
 * <fn1> has to be valid and <fn2> may be NULL. If both pointers are
 * non-NULL then the file is moved, otherwise it is deleted.  The
 * entry of the registrykey is always appended with two zero
 * terminated strings. If <fn2> is NULL then the second entry is
 * simply a single 0-byte. Otherwise the second filename goes
 * there. The entries are prepended with \??\ before the path and the
 * second filename gets also a '!' as the first character if
 * MOVEFILE_REPLACE_EXISTING is set. After the final string another
 * 0-byte follows to indicate the end of the strings.
 * i.e.:
 * \??\D:\test\file1[0]
 * !\??\D:\test\file1_renamed[0]
 * \??\D:\Test|delete[0]
 * [0]                        <- file is to be deleted, second string empty
 * \??\D:\test\file2[0]
 * !\??\D:\test\file2_renamed[0]
 * [0]                        <- indicates end of strings
 *
 * or:
 * \??\D:\test\file1[0]
 * !\??\D:\test\file1_renamed[0]
 * \??\D:\Test|delete[0]
 * [0]                        <- file is to be deleted, second string empty
 * [0]                        <- indicates end of strings
 *
 */
static BOOL add_boot_rename_entry( LPCWSTR source, LPCWSTR dest, DWORD flags )
{
    static const WCHAR ValueName[] = {'P','e','n','d','i','n','g',
                                      'F','i','l','e','R','e','n','a','m','e',
                                      'O','p','e','r','a','t','i','o','n','s',0};

    UNICODE_STRING KeyName = RTL_CONSTANT_STRING(L"\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\Control\\Session Manager");

    static const int info_size = FIELD_OFFSET( KEY_VALUE_PARTIAL_INFORMATION, Data );

    OBJECT_ATTRIBUTES ObjectAttributes;
    UNICODE_STRING nameW, source_name, dest_name;
    KEY_VALUE_PARTIAL_INFORMATION *info;
    BOOL rc = FALSE;
    HANDLE Reboot = NULL;
    DWORD len1, len2;
    DWORD DestLen = 0;
    DWORD DataSize = 0;
    BYTE *Buffer = NULL;
    WCHAR *p;
    NTSTATUS Status;

    TRACE("add_boot_rename_entry( %S, %S, %d ) \n", source, dest, flags);

    if(dest)
        DestLen = wcslen(dest);

    if (!RtlDosPathNameToNtPathName_U( source, &source_name, NULL, NULL ))
    {
        SetLastError( ERROR_PATH_NOT_FOUND );
        return FALSE;
    }
    dest_name.Buffer = NULL;
    if (DestLen && !RtlDosPathNameToNtPathName_U( dest, &dest_name, NULL, NULL ))
    {
        RtlFreeHeap( RtlGetProcessHeap(), 0, source_name.Buffer );
        SetLastError( ERROR_PATH_NOT_FOUND );
        return FALSE;
    }

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

     Status = NtCreateKey(&Reboot, 
                          KEY_QUERY_VALUE | KEY_SET_VALUE,
                          &ObjectAttributes,
                          0,
                          NULL,
                          REG_OPTION_NON_VOLATILE,
                          NULL);

     if (Status == STATUS_ACCESS_DENIED)
     {
         Status = NtCreateKey(
             &Reboot, 
             KEY_QUERY_VALUE | KEY_SET_VALUE,
             &ObjectAttributes,
             0,
             NULL,
             REG_OPTION_BACKUP_RESTORE,
             NULL);
     }

    if (!NT_SUCCESS(Status))
    {
        WARN("NtCreateKey() failed (Status 0x%lx)\n", Status);
        if (source_name.Buffer)
            RtlFreeHeap(RtlGetProcessHeap(), 0, source_name.Buffer);
        if (dest_name.Buffer)
            RtlFreeHeap(RtlGetProcessHeap(), 0, dest_name.Buffer);
        return FALSE;
    }

    len1 = source_name.Length + sizeof(WCHAR);
    if (DestLen)
    {
        len2 = dest_name.Length + sizeof(WCHAR);
        if (flags & MOVEFILE_REPLACE_EXISTING)
            len2 += sizeof(WCHAR); /* Plus 1 because of the leading '!' */
    }
    else
    {
        len2 = sizeof(WCHAR); /* minimum is the 0 characters for the empty second string */
    }

    RtlInitUnicodeString( &nameW, ValueName );

    /* First we check if the key exists and if so how many bytes it already contains. */
    Status = NtQueryValueKey(
        Reboot,
        &nameW,
        KeyValuePartialInformation,
        NULL,
        0, 
        &DataSize );
    if ((Status == STATUS_BUFFER_OVERFLOW) ||
        (Status == STATUS_BUFFER_TOO_SMALL))
    {
        if (!(Buffer = HeapAlloc(GetProcessHeap(), 0, DataSize + len1 + len2 + sizeof(WCHAR))))
            goto Quit;
        Status = NtQueryValueKey(Reboot, &nameW, KeyValuePartialInformation,
            Buffer, DataSize, &DataSize);
        if(!NT_SUCCESS(Status))
            goto Quit;
        info = (KEY_VALUE_PARTIAL_INFORMATION *)Buffer;
        if (info->Type != REG_MULTI_SZ) goto Quit;
        if (DataSize > sizeof(info)) DataSize -= sizeof(WCHAR);  /* remove terminating null (will be added back later) */
    }
    else
    {
        DataSize = info_size;
        if (!(Buffer = HeapAlloc( GetProcessHeap(), 0, DataSize + len1 + len2 + sizeof(WCHAR) )))
            goto Quit;
    }

    memcpy( Buffer + DataSize, source_name.Buffer, len1 );
    DataSize += len1;
    p = (WCHAR *)(Buffer + DataSize);
    if (DestLen)
    {
        if (flags & MOVEFILE_REPLACE_EXISTING)
            *p++ = '!';
        memcpy( p, dest_name.Buffer, len2 );
        DataSize += len2;
    }
    else
    {
        *p = 0;
        DataSize += sizeof(WCHAR);
    }

    /* add final null */
    p = (WCHAR *)(Buffer + DataSize);
    *p = 0;
    DataSize += sizeof(WCHAR);

    rc = NT_SUCCESS(NtSetValueKey(Reboot, &nameW, 0, REG_MULTI_SZ, Buffer + info_size, DataSize - info_size));

 Quit:
    RtlFreeHeap(RtlGetProcessHeap(), 0, source_name.Buffer);
    if (dest_name.Buffer)
        RtlFreeHeap(RtlGetProcessHeap(), 0, dest_name.Buffer);
    NtClose(Reboot);
    if(Buffer)
        HeapFree(GetProcessHeap(), 0, Buffer);
    return(rc);
}
Beispiel #28
0
/*
 * @unimplemented
 */
PSID
WINAPI
GetSiteSidFromToken(IN HANDLE TokenHandle)
{
    PTOKEN_GROUPS RestrictedSids;
    ULONG RetLen;
    UINT i;
    NTSTATUS Status;
    PSID PSiteSid = NULL;
    SID_IDENTIFIER_AUTHORITY InternetSiteAuthority = {SECURITY_INTERNETSITE_AUTHORITY};

    Status = NtQueryInformationToken(TokenHandle,
                                     TokenRestrictedSids,
                                     NULL,
                                     0,
                                     &RetLen);
    if (Status != STATUS_BUFFER_TOO_SMALL)
    {
        SetLastError(RtlNtStatusToDosError(Status));
        return NULL;
    }

    RestrictedSids = (PTOKEN_GROUPS)RtlAllocateHeap(RtlGetProcessHeap(),
                                                    0,
                                                    RetLen);
    if (RestrictedSids == NULL)
    {
        SetLastError(ERROR_OUTOFMEMORY);
        return NULL;
    }

    Status = NtQueryInformationToken(TokenHandle,
                                     TokenRestrictedSids,
                                     RestrictedSids,
                                     RetLen,
                                     &RetLen);
    if (NT_SUCCESS(Status))
    {
        for (i = 0; i < RestrictedSids->GroupCount; i++)
        {
            SID* RSSid = RestrictedSids->Groups[i].Sid;

            if (RtlCompareMemory(&(RSSid->IdentifierAuthority),
                                 &InternetSiteAuthority,
                                 sizeof(SID_IDENTIFIER_AUTHORITY)) ==
                                 sizeof(SID_IDENTIFIER_AUTHORITY))
            {
                PSiteSid = RtlAllocateHeap(RtlGetProcessHeap(),
                                           0,
                                           RtlLengthSid((RestrictedSids->
                                                         Groups[i]).Sid));
                if (PSiteSid == NULL)
                {
                    SetLastError(ERROR_OUTOFMEMORY);
                }
                else
                {
                    RtlCopySid(RtlLengthSid(RestrictedSids->Groups[i].Sid),
                               PSiteSid,
                               RestrictedSids->Groups[i].Sid);
                }

                break;
            }
        }
    }
    else
    {
        SetLastError(RtlNtStatusToDosError(Status));
    }

    RtlFreeHeap(RtlGetProcessHeap(), 0, RestrictedSids);
    return PSiteSid;
}
Beispiel #29
0
NTSTATUS
SampRegQueryValue(IN HANDLE KeyHandle,
                  IN LPCWSTR ValueName,
                  OUT PULONG Type OPTIONAL,
                  OUT PVOID Data OPTIONAL,
                  IN OUT PULONG DataLength OPTIONAL)
{
    PKEY_VALUE_PARTIAL_INFORMATION ValueInfo;
    UNICODE_STRING Name;
    ULONG BufferLength = 0;
    NTSTATUS Status;

    RtlInitUnicodeString(&Name,
                         ValueName);

    if (DataLength != NULL)
        BufferLength = *DataLength;

    BufferLength += FIELD_OFFSET(KEY_VALUE_PARTIAL_INFORMATION, Data);

    /* Allocate memory for the value */
    ValueInfo = RtlAllocateHeap(RtlGetProcessHeap(), 0, BufferLength);
    if (ValueInfo == NULL)
        return STATUS_NO_MEMORY;

    /* Query the value */
    Status = ZwQueryValueKey(KeyHandle,
                             &Name,
                             KeyValuePartialInformation,
                             ValueInfo,
                             BufferLength,
                             &BufferLength);
    if ((NT_SUCCESS(Status)) || (Status == STATUS_BUFFER_OVERFLOW))
    {
        if (Type != NULL)
            *Type = ValueInfo->Type;

        if (DataLength != NULL)
            *DataLength = ValueInfo->DataLength;
    }

    /* Check if the caller wanted data back, and we got it */
    if ((NT_SUCCESS(Status)) && (Data != NULL))
    {
        /* Copy it */
        RtlMoveMemory(Data,
                      ValueInfo->Data,
                      ValueInfo->DataLength);

        /* if the type is REG_SZ and data is not 0-terminated
         * and there is enough space in the buffer NT appends a \0 */
        if (IsStringType(ValueInfo->Type) &&
            ValueInfo->DataLength <= *DataLength - sizeof(WCHAR))
        {
            WCHAR *ptr = (WCHAR *)((ULONG_PTR)Data + ValueInfo->DataLength);
            if ((ptr > (WCHAR *)Data) && ptr[-1])
                *ptr = 0;
        }
    }

    /* Free the memory and return status */
    RtlFreeHeap(RtlGetProcessHeap(), 0, ValueInfo);

    if ((Data == NULL) && (Status == STATUS_BUFFER_OVERFLOW))
        Status = STATUS_SUCCESS;

    return Status;
}
Beispiel #30
0
static NTSTATUS
Fat12WriteFAT(IN HANDLE FileHandle,
              IN ULONG SectorOffset,
              IN PFAT16_BOOT_SECTOR BootSector,
              IN OUT PFORMAT_CONTEXT Context)
{
    IO_STATUS_BLOCK IoStatusBlock;
    NTSTATUS Status;
    PUCHAR Buffer;
    LARGE_INTEGER FileOffset;
    ULONG i;
    ULONG Size;
    ULONG Sectors;

    /* Allocate buffer */
    Buffer = (PUCHAR)RtlAllocateHeap(RtlGetProcessHeap(),
                                     0,
                                     32 * 1024);
    if (Buffer == NULL)
        return STATUS_INSUFFICIENT_RESOURCES;

    /* Zero the buffer */
    RtlZeroMemory(Buffer, 32 * 1024);

    /* FAT cluster 0 & 1*/
    Buffer[0] = 0xf8; /* Media type */
    Buffer[1] = 0xff;
    Buffer[2] = 0xff;

    /* Write first sector of the FAT */
    FileOffset.QuadPart = (SectorOffset + BootSector->ReservedSectors) * BootSector->BytesPerSector;
    Status = NtWriteFile(FileHandle,
                         NULL,
                         NULL,
                         NULL,
                         &IoStatusBlock,
                         Buffer,
                         BootSector->BytesPerSector,
                         &FileOffset,
                         NULL);
    if (!NT_SUCCESS(Status))
    {
        DPRINT("NtWriteFile() failed (Status %lx)\n", Status);
        goto done;
    }

    UpdateProgress(Context, 1);

    /* Zero the begin of the buffer */
    RtlZeroMemory(Buffer, 3);

    /* Zero the rest of the FAT */
    Sectors = 32 * 1024 / BootSector->BytesPerSector;
    for (i = 1; i < (ULONG)BootSector->FATSectors; i += Sectors)
    {
        /* Zero some sectors of the FAT */
        FileOffset.QuadPart = (SectorOffset + BootSector->ReservedSectors + i) * BootSector->BytesPerSector;
        if (((ULONG)BootSector->FATSectors - i) <= Sectors)
        {
            Sectors = (ULONG)BootSector->FATSectors - i;
        }

        Size = Sectors * BootSector->BytesPerSector;
        Status = NtWriteFile(FileHandle,
                             NULL,
                             NULL,
                             NULL,
                             &IoStatusBlock,
                             Buffer,
                             Size,
                             &FileOffset,
                             NULL);
        if (!NT_SUCCESS(Status))
        {
            DPRINT("NtWriteFile() failed (Status %lx)\n", Status);
            goto done;
        }

        UpdateProgress(Context, Sectors);
    }

done:
    /* Free the buffer */
    RtlFreeHeap(RtlGetProcessHeap(), 0, Buffer);
    return Status;
}