static int OnObjectIdMoreClick(HWND hDlg)
{
    TFileTestData * pData = GetDialogData(hDlg);
    FILE_OBJECTID_BUFFER ObjId = {0};
    UINT_PTR nAction;
    HANDLE hFile = INVALID_HANDLE_VALUE;
    TCHAR szObjectID[0x40];
    DWORD dwFlagsAndAttributes = 0;
    DWORD dwDesiredAccess = FILE_READ_ATTRIBUTES;
    DWORD dwBytesReturned;
    DWORD dwIoctlCode = FSCTL_CREATE_OR_GET_OBJECT_ID;
    int nError = ERROR_SUCCESS;

    // Ask the user for the action
    nAction = ObjectIDActionDialog(hDlg);
    if(nAction == IDCANCEL)
        return TRUE;
    SaveDialog(hDlg);
    
    // Use the proper desired access
    // Note that we also need restore privilege in order to succeed
    if(nAction == IDC_SET_OBJECT_ID)
    {
        dwFlagsAndAttributes = FILE_FLAG_BACKUP_SEMANTICS;
        dwDesiredAccess = FILE_WRITE_DATA;
    }

    // Convert the file name to the NT file name
    hFile = CreateFile(pData->szFileName1, dwDesiredAccess, 0, NULL, OPEN_EXISTING, dwFlagsAndAttributes, NULL);
    if(hFile == INVALID_HANDLE_VALUE)
        nError = GetLastError();

    // Perform an action specific to 
    if(nError == ERROR_SUCCESS)
    {
        switch(nAction)
        {
            case IDC_CREATE_OR_GET:
            case IDC_GET_OBJECT_ID:

                if(nAction == IDC_GET_OBJECT_ID)
                    dwIoctlCode = FSCTL_GET_OBJECT_ID;

                memset(&ObjId, 0, sizeof(FILE_OBJECTID_BUFFER));
                if(DeviceIoControl(hFile, dwIoctlCode,
                                          NULL,
                                          0,
                                         &ObjId,
                                          sizeof(FILE_OBJECTID_BUFFER),
                                         &dwBytesReturned,
                                          NULL))
                {
                    ObjectIDToString(ObjId.ObjectId, pData->szFileName1, szObjectID);
                    SetDlgItemText(hDlg, IDC_OBJECT_ID, szObjectID);
                }
                else
                {
                    nError = GetLastError();
                }
                break;
            
            case IDC_SET_OBJECT_ID:

                GetDlgItemText(hDlg, IDC_OBJECT_ID, szObjectID, _maxchars(szObjectID));
                nError = StringToFileID(szObjectID, NULL, ObjId.ObjectId, NULL);
                if(nError != ERROR_SUCCESS)
                    break;

                if(!DeviceIoControl(hFile, FSCTL_SET_OBJECT_ID,
                                          &ObjId,
                                           sizeof(FILE_OBJECTID_BUFFER),
                                           NULL,
                                           0,
                                          &dwBytesReturned,
                                           NULL))
                {
                    nError = GetLastError();
                }
                break;
        }
    }

    if(hFile != INVALID_HANDLE_VALUE)
        CloseHandle(hFile);
    SetResultInfo(hDlg, nError);
    return TRUE;
}
예제 #2
0
static int OnCreateFileClick(HWND hDlg)
{
    TFileTestData * pData = GetDialogData(hDlg);
    OBJECT_ATTRIBUTES ObjAttr;
    IO_STATUS_BLOCK IoStatus;
    UNICODE_STRING FileName;
    UNICODE_STRING DirName;
    LARGE_INTEGER AllocationSize;
    NTSTATUS Status = STATUS_SUCCESS;
    HANDLE SaveTransactionHandle = NULL;
    TCHAR szFileName[MAX_NT_PATH];
    TCHAR szDirName[MAX_NT_PATH];
    DWORD cbObjectID = 0;
    BYTE ObjectID[0x10];

    // Close the handle, if already open
    if(IsHandleValid(pData->hDirectory) || IsHandleValid(pData->hFile))
        OnNtCloseClick(hDlg);

    // Get the various create options
    if(SaveDialog(hDlg) != ERROR_SUCCESS)
        return FALSE;

    if(pData->bUseTransaction && pfnRtlSetCurrentTransaction != NULL)
    {
        SaveTransactionHandle = pfnRtlGetCurrentTransaction();
        pfnRtlSetCurrentTransaction(pData->hTransaction);
    }

    // Get the directory name from the dialog data
    StringCchCopy(szDirName, _countof(szDirName), pData->szDirName);
    StringCchCopy(szFileName, _countof(szFileName), pData->szFileName1);

    // If we are about to open a file by ID, and we have no relative directory,
    // try to take the directory from the file name
    if(szDirName[0] == 0 && (pData->dwCreateOptions & FILE_OPEN_BY_FILE_ID))
    {
        LPTSTR szFullName = pData->szFileName1;
        LPTSTR szFileId = _tcsrchr(szFullName, _T('\\'));
        size_t nLength = szFileId - szFullName + 1;

        if(szFileId != NULL)
        {
            StringCchCopy(szDirName, nLength, szFullName);
            StringCchCopy(szFileName, _countof(szFileName), szFileId + 1);
        }
    }

    // Open the relative file (if any)
    if(szDirName[0] != 0)
    {
        RtlInitUnicodeString(&DirName, szDirName);
        InitializeObjectAttributes(&ObjAttr, &DirName, pData->dwObjAttrFlags, 0, NULL);
        Status = NtOpenFile(&pData->hDirectory,
                             pData->dwDesiredAccessRF,
                            &ObjAttr,
                            &IoStatus,
                             pData->dwShareAccessRF,
                             pData->dwOpenOptionsRF);

        if(!NT_SUCCESS(Status))
        {
            SetResultInfo(hDlg, Status, NULL, IoStatus.Information);
            return TRUE;
        }
    }

    // Prepare the file open
    if(NT_SUCCESS(Status))
    {
        RtlInitUnicodeString(&FileName, szFileName);

        // If open by ID required, set the ID to the string
        if(pData->dwCreateOptions & FILE_OPEN_BY_FILE_ID)
        {
            // Convert object ID to binary value
            if(StringToFileID(szFileName, NULL, ObjectID, &cbObjectID) != ERROR_SUCCESS)
                return TRUE;

            // Set the object ID to the UNICODE_STRING
            FileName.MaximumLength = 
            FileName.Length = (USHORT)cbObjectID;
            FileName.Buffer = (PWSTR)ObjectID;
        }

        ZeroMemory(&IoStatus, sizeof(IO_STATUS_BLOCK));
        InitializeObjectAttributes(&ObjAttr, &FileName, pData->dwObjAttrFlags, pData->hDirectory, NULL);
        AllocationSize.QuadPart = (LONGLONG)pData->AllocationSize;
           
        // Invoke breakpoint if the user wants to
        if(IsDlgButtonChecked(hDlg, IDC_BREAKPOINT) == BST_CHECKED)
            DebugBreak();

        Status = NtCreateFile(&pData->hFile,
                               pData->dwDesiredAccess,
                              &ObjAttr,
                              &IoStatus,
                              &AllocationSize,
                               pData->dwFileAttributes,
                               pData->dwShareAccess,
                               pData->dwCreateDisposition2,
                               pData->dwCreateOptions,
                               pData->pFileEa,
                               pData->dwEaSize);
        SetResultInfo(hDlg, Status, pData->hFile, IoStatus.Information);

        // If this operation failed, we close the directory as well
        if(!NT_SUCCESS(Status) && pData->hDirectory != NULL)
        {
            NtClose(pData->hDirectory);
            pData->hDirectory = NULL;
        }
    }

    if(pData->bUseTransaction && pfnRtlSetCurrentTransaction != NULL)
    {
        pfnRtlSetCurrentTransaction(SaveTransactionHandle);
        SaveTransactionHandle = NULL;
    }

    return TRUE;
}