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; }
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; }