static DWORD NtOpenObject(OBJECT_TYPE type, PHANDLE phandle, DWORD access, LPCWSTR path) { UNICODE_STRING ustr; RtlInitUnicodeString(&ustr, path); OBJECT_ATTRIBUTES open_struct = { sizeof(OBJECT_ATTRIBUTES), 0x00, &ustr, 0x40 }; if (type != FILE_OBJECT) access |= STANDARD_RIGHTS_READ; IO_STATUS_BLOCK ioStatusBlock; switch (type) { case DIRECTORY_OBJECT: return NtOpenDirectoryObject(phandle, access, &open_struct); case SYMBOLICLINK_OBJECT: return NtOpenSymbolicLinkObject(phandle, access, &open_struct); case MUTANT_OBJECT: return NtOpenMutant(phandle, access, &open_struct); case SECTION_OBJECT: return NtOpenSection(phandle, access, &open_struct); case EVENT_OBJECT: return NtOpenEvent(phandle, access, &open_struct); case SEMAPHORE_OBJECT: return NtOpenSemaphore(phandle, access, &open_struct); case TIMER_OBJECT: return NtOpenTimer(phandle, access, &open_struct); case KEY_OBJECT: return NtOpenKey(phandle, access, &open_struct); case EVENTPAIR_OBJECT: return NtOpenEventPair(phandle, access, &open_struct); case IOCOMPLETION_OBJECT: return NtOpenIoCompletion(phandle, access, &open_struct); case FILE_OBJECT: return NtOpenFile(phandle, access, &open_struct, &ioStatusBlock, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, 0); default: return ERROR_INVALID_FUNCTION; } }
/* * @implemented */ HANDLE WINAPI OpenSemaphoreW(IN DWORD dwDesiredAccess, IN BOOL bInheritHandle, IN LPCWSTR lpName) { OBJECT_ATTRIBUTES ObjectAttributes; UNICODE_STRING ObjectName; NTSTATUS Status; HANDLE Handle; /* Make sure we got a name */ if (!lpName) { /* Fail without one */ SetLastErrorByStatus(STATUS_INVALID_PARAMETER); return NULL; } /* Initialize the object name and attributes */ RtlInitUnicodeString(&ObjectName, lpName); InitializeObjectAttributes(&ObjectAttributes, &ObjectName, bInheritHandle ? OBJ_INHERIT : 0, hBaseDir, NULL); /* Open the semaphore */ Status = NtOpenSemaphore(&Handle, dwDesiredAccess, &ObjectAttributes); if (!NT_SUCCESS(Status)) { /* Convert the status and fail */ SetLastErrorByStatus(Status); return NULL; } /* Return the handle */ return Handle; }
HANDLE APIENTRY OpenSemaphoreW( DWORD dwDesiredAccess, BOOL bInheritHandle, LPCWSTR lpName ) { OBJECT_ATTRIBUTES Obja; UNICODE_STRING ObjectName; NTSTATUS Status; HANDLE Object; if ( !lpName ) { BaseSetLastNTError(STATUS_INVALID_PARAMETER); return NULL; } RtlInitUnicodeString(&ObjectName,lpName); InitializeObjectAttributes( &Obja, &ObjectName, (bInheritHandle ? OBJ_INHERIT : 0), BaseGetNamedObjectDirectory(), NULL ); Status = NtOpenSemaphore( &Object, dwDesiredAccess, &Obja ); if ( !NT_SUCCESS(Status) ) { BaseSetLastNTError(Status); return NULL; } return Object; }
/* * propOpenCurrentObject * * Purpose: * * Opens currently viewed object depending on type * */ BOOL propOpenCurrentObject( _In_ PROP_OBJECT_INFO *Context, _Inout_ PHANDLE phObject, _In_ ACCESS_MASK DesiredAccess ) { BOOL bResult; HANDLE hObject, hDirectory; NTSTATUS status; UNICODE_STRING ustr; OBJECT_ATTRIBUTES obja; IO_STATUS_BLOCK iost; bResult = FALSE; if (Context == NULL) { return bResult; } //we don't know who is it if (Context->TypeIndex == TYPE_UNKNOWN) { SetLastError(ERROR_UNSUPPORTED_TYPE); return bResult; } if (phObject == NULL) { SetLastError(ERROR_OBJECT_NOT_FOUND); return bResult; } if (Context->lpObjectName == NULL) { SetLastError(ERROR_OBJECT_NOT_FOUND); return bResult; } if (Context->lpCurrentObjectPath == NULL) { SetLastError(ERROR_OBJECT_NOT_FOUND); return bResult; } //ports not supported if ( (Context->TypeIndex == TYPE_PORT) || (Context->TypeIndex == TYPE_FLTCOMM_PORT) || (Context->TypeIndex == TYPE_FLTCONN_PORT) || (Context->TypeIndex == TYPE_WAITABLEPORT) ) { SetLastError(ERROR_UNSUPPORTED_TYPE); return bResult; } hDirectory = NULL; if (DesiredAccess == 0) { DesiredAccess = 1; } //handle directory type if (Context->TypeIndex == TYPE_DIRECTORY) { //if this is root, then root hDirectory = NULL if (_strcmpi(Context->lpObjectName, L"\\") != 0) { //else open directory that holds this object hDirectory = supOpenDirectoryForObject(Context->lpObjectName, Context->lpCurrentObjectPath); if (hDirectory == NULL) { SetLastError(ERROR_OBJECT_NOT_FOUND); return bResult; } } //open object in directory RtlSecureZeroMemory(&ustr, sizeof(ustr)); RtlInitUnicodeString(&ustr, Context->lpObjectName); InitializeObjectAttributes(&obja, &ustr, OBJ_CASE_INSENSITIVE, hDirectory, NULL); hObject = NULL; status = NtOpenDirectoryObject(&hObject, DesiredAccess, &obja); //DIRECTORY_QUERY for query SetLastError(RtlNtStatusToDosError(status)); bResult = ((NT_SUCCESS(status)) && (hObject != NULL)); if (bResult && phObject) { *phObject = hObject; } //dont forget to close directory handle if it was opened if (hDirectory != NULL) { NtClose(hDirectory); } return bResult; } //handle window station type if (Context->TypeIndex == TYPE_WINSTATION) { hObject = OpenWindowStation(Context->lpObjectName, FALSE, DesiredAccess); //WINSTA_READATTRIBUTES for query bResult = (hObject != NULL); if (bResult && phObject) { *phObject = hObject; } return bResult; } //handle desktop type if (Context->TypeIndex == TYPE_DESKTOP) { hObject = OpenDesktop(Context->lpObjectName, 0, FALSE, DesiredAccess); //DESKTOP_READOBJECTS for query bResult = (hObject != NULL); if (bResult && phObject) { *phObject = hObject; } return bResult; } //open directory which current object belongs hDirectory = supOpenDirectoryForObject(Context->lpObjectName, Context->lpCurrentObjectPath); if (hDirectory == NULL) { SetLastError(ERROR_OBJECT_NOT_FOUND); return bResult; } RtlSecureZeroMemory(&ustr, sizeof(ustr)); RtlInitUnicodeString(&ustr, Context->lpObjectName); InitializeObjectAttributes(&obja, &ustr, OBJ_CASE_INSENSITIVE, hDirectory, NULL); status = STATUS_UNSUCCESSFUL; hObject = NULL; //handle supported objects switch (Context->TypeIndex) { case TYPE_DEVICE: //FILE_OBJECT status = NtCreateFile(&hObject, DesiredAccess, &obja, &iost, NULL, 0, FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE, FILE_OPEN, 0, NULL, 0);//generic access rights break; case TYPE_MUTANT: status = NtOpenMutant(&hObject, DesiredAccess, &obja); //MUTANT_QUERY_STATE for query break; case TYPE_KEY: status = NtOpenKey(&hObject, DesiredAccess, &obja); //KEY_QUERY_VALUE for query break; case TYPE_SEMAPHORE: status = NtOpenSemaphore(&hObject, DesiredAccess, &obja); //SEMAPHORE_QUERY_STATE for query break; case TYPE_TIMER: status = NtOpenTimer(&hObject, DesiredAccess, &obja); //TIMER_QUERY_STATE for query break; case TYPE_EVENT: status = NtOpenEvent(&hObject, DesiredAccess, &obja); //EVENT_QUERY_STATE for query break; case TYPE_EVENTPAIR: status = NtOpenEventPair(&hObject, DesiredAccess, &obja); //generic access break; case TYPE_SYMLINK: status = NtOpenSymbolicLinkObject(&hObject, DesiredAccess, &obja); //SYMBOLIC_LINK_QUERY for query break; case TYPE_IOCOMPLETION: status = NtOpenIoCompletion(&hObject, DesiredAccess, &obja); //IO_COMPLETION_QUERY_STATE for query break; case TYPE_SECTION: status = NtOpenSection(&hObject, DesiredAccess, &obja); //SECTION_QUERY for query break; case TYPE_JOB: status = NtOpenJobObject(&hObject, DesiredAccess, &obja); //JOB_OBJECT_QUERY for query break; } SetLastError(RtlNtStatusToDosError(status)); NtClose(hDirectory); bResult = ((NT_SUCCESS(status)) && (hObject != NULL)); if (bResult && phObject) { *phObject = hObject; } return bResult; }