Index: modules/rostests/winetests/ntdll/CMakeLists.txt =================================================================== --- modules/rostests/winetests/ntdll/CMakeLists.txt (revision 70979) +++ modules/rostests/winetests/ntdll/CMakeLists.txt (working copy) @@ -28,7 +28,7 @@ add_executable(ntdll_winetest ${SOURCE}) set_module_type(ntdll_winetest win32cui) -add_importlibs(ntdll_winetest user32 msvcrt kernel32 ntdll) +add_importlibs(ntdll_winetest user32 ole32 advapi32 msvcrt kernel32 ntdll) add_cd_file(TARGET ntdll_winetest DESTINATION reactos/bin FOR all) if(NOT MSVC) Index: modules/rostests/winetests/ntdll/directory.c =================================================================== --- modules/rostests/winetests/ntdll/directory.c (revision 70979) +++ modules/rostests/winetests/ntdll/directory.c (working copy) @@ -59,6 +59,7 @@ int nfound; /* How many were found (expect 1) */ WCHAR nameW[20]; /* unicode version of name (filled in later) */ } testfiles[] = { + { 0, FILE_ATTRIBUTE_NORMAL, "longfilename.tmp", NULL, "normal" }, { 0, FILE_ATTRIBUTE_NORMAL, "n.tmp", NULL, "normal" }, { 0, FILE_ATTRIBUTE_HIDDEN, "h.tmp", NULL, "hidden" }, { 0, FILE_ATTRIBUTE_SYSTEM, "s.tmp", NULL, "system" }, @@ -228,10 +229,17 @@ static void test_NtQueryDirectoryFile(void) { OBJECT_ATTRIBUTES attr; - UNICODE_STRING ntdirname; + UNICODE_STRING ntdirname, mask; char testdirA[MAX_PATH]; WCHAR testdirW[MAX_PATH]; int i; + IO_STATUS_BLOCK io; + WCHAR short_name[12]; + UINT data_size; + BYTE data[8192]; + FILE_BOTH_DIRECTORY_INFORMATION *fbdi = (FILE_BOTH_DIRECTORY_INFORMATION*)data; + DWORD status; + HANDLE dirh; /* Clean up from prior aborted run, if any, then set up test files */ ok(GetTempPathA(MAX_PATH, testdirA), "couldn't get temp dir\n"); @@ -254,8 +262,6 @@ for (i = 0; testfiles[i].name; i++) { - UNICODE_STRING mask; - if (testfiles[i].nameW[0] == '.') continue; /* . and .. as masks are broken on Windows */ mask.Buffer = testfiles[i].nameW; mask.Length = mask.MaximumLength = lstrlenW(testfiles[i].nameW) * sizeof(WCHAR); @@ -265,6 +271,35 @@ test_flags_NtQueryDirectoryFile(&attr, testdirA, &mask, TRUE, FALSE); } + /* short path passed as mask */ + status = pNtOpenFile(&dirh, SYNCHRONIZE | FILE_LIST_DIRECTORY, &attr, &io, FILE_SHARE_READ, + FILE_SYNCHRONOUS_IO_NONALERT | FILE_OPEN_FOR_BACKUP_INTENT | FILE_DIRECTORY_FILE); + ok(status == STATUS_SUCCESS, "failed to open dir '%s'\n", testdirA); + if (status != STATUS_SUCCESS) { + skip("can't test if we can't open the directory\n"); + return; + } + mask.Buffer = testfiles[0].nameW; + mask.Length = mask.MaximumLength = lstrlenW(testfiles[0].nameW) * sizeof(WCHAR); + data_size = offsetof(FILE_BOTH_DIRECTORY_INFORMATION, FileName[256]); + pNtQueryDirectoryFile(dirh, 0, NULL, NULL, &io, data, data_size, + FileBothDirectoryInformation, TRUE, &mask, FALSE); + ok(U(io).Status == STATUS_SUCCESS, "failed to query directory; status %x\n", U(io).Status); + ok(fbdi->ShortName[0], "ShortName is empty\n"); + + mask.Length = mask.MaximumLength = fbdi->ShortNameLength; + memcpy(short_name, fbdi->ShortName, mask.Length); + mask.Buffer = short_name; + pNtQueryDirectoryFile(dirh, 0, NULL, NULL, &io, data, data_size, + FileBothDirectoryInformation, TRUE, &mask, TRUE); + ok(U(io).Status == STATUS_SUCCESS, "failed to query directory status %x\n", U(io).Status); + ok(fbdi->FileNameLength == strlen(testfiles[0].name)*sizeof(WCHAR) && + !memcmp(fbdi->FileName, testfiles[0].nameW, fbdi->FileNameLength), + "incorrect long file name: %s\n", wine_dbgstr_wn(fbdi->FileName, + fbdi->FileNameLength/sizeof(WCHAR))); + + pNtClose(dirh); + done: tear_down_attribute_test(testdirA); pRtlFreeUnicodeString(&ntdirname); Index: modules/rostests/winetests/ntdll/error.c =================================================================== --- modules/rostests/winetests/ntdll/error.c (revision 70979) +++ modules/rostests/winetests/ntdll/error.c (working copy) @@ -125,8 +125,10 @@ cmp(STATUS_DATATYPE_MISALIGNMENT, ERROR_NOACCESS); cmp(STATUS_ACCESS_VIOLATION, ERROR_NOACCESS); cmp2(STATUS_DATATYPE_MISALIGNMENT_ERROR, ERROR_NOACCESS); + cmp2(STATUS_MULTIPLE_FAULT_VIOLATION, ERROR_MULTIPLE_FAULT_VIOLATION); cmp(STATUS_CTL_FILE_NOT_SUPPORTED, ERROR_NOT_SUPPORTED); cmp(STATUS_PORT_ALREADY_SET, ERROR_INVALID_PARAMETER); + cmp2(STATUS_PORT_NOT_SET, ERROR_PORT_NOT_SET); cmp(STATUS_SECTION_NOT_IMAGE, ERROR_INVALID_PARAMETER); cmp(STATUS_BAD_WORKING_SET_LIMIT, ERROR_INVALID_PARAMETER); cmp(STATUS_WORKING_SET_LIMIT_RANGE, ERROR_INVALID_PARAMETER); @@ -140,6 +142,7 @@ cmp(STATUS_INVALID_CID, ERROR_INVALID_PARAMETER); cmp(STATUS_STACK_OVERFLOW, ERROR_STACK_OVERFLOW); cmp(STATUS_BAD_INITIAL_STACK, ERROR_STACK_OVERFLOW); + cmp4(STATUS_STACK_OVERFLOW_READ, ERROR_STACK_OVERFLOW_READ, ERROR_STACK_OVERFLOW); cmp(STATUS_INVALID_VOLUME_LABEL, ERROR_LABEL_TOO_LONG); cmp(STATUS_SECTION_NOT_EXTENDED, ERROR_OUTOFMEMORY); cmp(STATUS_NOT_MAPPED_DATA, ERROR_INVALID_ADDRESS); @@ -148,18 +151,24 @@ cmp(STATUS_INVALID_INFO_CLASS, ERROR_INVALID_PARAMETER); cmp(STATUS_SUSPEND_COUNT_EXCEEDED, ERROR_SIGNAL_REFUSED); cmp(STATUS_NOTIFY_ENUM_DIR, ERROR_NOTIFY_ENUM_DIR); + cmp2(STATUS_BAD_CURRENT_DIRECTORY, ERROR_BAD_CURRENT_DIRECTORY); cmp(STATUS_REGISTRY_RECOVERED, ERROR_REGISTRY_RECOVERED); + cmp2(STATUS_REGISTRY_HIVE_RECOVERED, ERROR_REGISTRY_HIVE_RECOVERED); cmp(STATUS_REGISTRY_IO_FAILED, ERROR_REGISTRY_IO_FAILED); cmp(STATUS_NOT_REGISTRY_FILE, ERROR_NOT_REGISTRY_FILE); + cmp2(STATUS_CANNOT_LOAD_REGISTRY_FILE, ERROR_CANNOT_LOAD_REGISTRY_FILE); + cmp2(STATUS_SYSTEM_HIVE_TOO_LARGE, ERROR_SYSTEM_HIVE_TOO_LARGE); cmp(STATUS_KEY_DELETED, ERROR_KEY_DELETED); cmp(STATUS_NO_LOG_SPACE, ERROR_NO_LOG_SPACE); cmp(STATUS_KEY_HAS_CHILDREN, ERROR_KEY_HAS_CHILDREN); cmp(STATUS_CHILD_MUST_BE_VOLATILE, ERROR_CHILD_MUST_BE_VOLATILE); cmp(STATUS_REGISTRY_CORRUPT, ERROR_BADDB); + cmp2(STATUS_REGISTRY_QUOTA_LIMIT, ERROR_REGISTRY_QUOTA_LIMIT); cmp(STATUS_DLL_NOT_FOUND, ERROR_MOD_NOT_FOUND); cmp2(STATUS_OPEN_FAILED, ERROR_NET_OPEN_FAILED); cmp2(STATUS_IO_PRIVILEGE_FAILED, ERROR_IO_PRIVILEGE_FAILED); cmp(STATUS_DLL_INIT_FAILED, ERROR_DLL_INIT_FAILED); + cmp2(STATUS_DLL_INIT_FAILED_LOGOFF, ERROR_DLL_INIT_FAILED_LOGOFF); cmp2(STATUS_INVALID_IMPORT_OF_NON_DLL, ERROR_INVALID_IMPORT_OF_NON_DLL); cmp(STATUS_ORDINAL_NOT_FOUND, ERROR_INVALID_ORDINAL); cmp(STATUS_DRIVER_ORDINAL_NOT_FOUND, ERROR_INVALID_ORDINAL); @@ -166,11 +175,22 @@ cmp2(STATUS_DRIVER_UNABLE_TO_LOAD, ERROR_BAD_DRIVER); cmp(STATUS_ENTRYPOINT_NOT_FOUND, ERROR_PROC_NOT_FOUND); cmp(STATUS_DRIVER_ENTRYPOINT_NOT_FOUND, ERROR_PROC_NOT_FOUND); + cmp2(STATUS_BAD_DLL_ENTRYPOINT, ERROR_BAD_DLL_ENTRYPOINT); + cmp2(STATUS_BAD_SERVICE_ENTRYPOINT, ERROR_BAD_SERVICE_ENTRYPOINT); + cmp2(STATUS_FAILED_DRIVER_ENTRY, ERROR_FAILED_DRIVER_ENTRY); + cmp2(STATUS_DLL_MIGHT_BE_INSECURE, ERROR_DLL_MIGHT_BE_INSECURE); + cmp2(STATUS_DLL_MIGHT_BE_INCOMPATIBLE, ERROR_DLL_MIGHT_BE_INCOMPATIBLE); + cmp2(STATUS_ILLEGAL_DLL_RELOCATION, ERROR_ILLEGAL_DLL_RELOCATION); + cmp2(STATUS_NOT_SAFE_MODE_DRIVER, ERROR_NOT_SAFE_MODE_DRIVER); + cmp2(STATUS_DRIVER_DATABASE_ERROR, ERROR_DRIVER_DATABASE_ERROR); cmp(STATUS_PENDING, ERROR_IO_PENDING); cmp(STATUS_MORE_ENTRIES, ERROR_MORE_DATA); cmp(STATUS_INTEGER_OVERFLOW, ERROR_ARITHMETIC_OVERFLOW); cmp(STATUS_BUFFER_OVERFLOW, ERROR_MORE_DATA); + cmp2(STATUS_MARSHALL_OVERFLOW, ERROR_MARSHALL_OVERFLOW); cmp(STATUS_NO_MORE_FILES, ERROR_NO_MORE_FILES); + cmp2(STATUS_REDIRECTOR_HAS_OPEN_HANDLES, ERROR_REDIRECTOR_HAS_OPEN_HANDLES); + cmp2(STATUS_SERVER_HAS_OPEN_HANDLES, ERROR_SERVER_HAS_OPEN_HANDLES); cmp2(STATUS_HANDLES_CLOSED, ERROR_HANDLES_CLOSED); cmp(STATUS_NO_INHERITANCE, ERROR_NO_INHERITANCE); cmp(STATUS_NO_MORE_EAS, ERROR_NO_MORE_ITEMS); @@ -183,8 +203,19 @@ cmp(STATUS_ILLEGAL_FUNCTION, ERROR_INVALID_FUNCTION); cmp(STATUS_IN_PAGE_ERROR, ERROR_SWAPERROR); cmp(STATUS_PAGEFILE_QUOTA, ERROR_PAGEFILE_QUOTA); + cmp2(STATUS_PAGEFILE_QUOTA_EXCEEDED, ERROR_PAGEFILE_QUOTA_EXCEEDED); + cmp2(STATUS_PAGE_FAULT_TRANSITION, ERROR_PAGE_FAULT_TRANSITION); + cmp2(STATUS_PAGE_FAULT_DEMAND_ZERO, ERROR_PAGE_FAULT_DEMAND_ZERO); + cmp2(STATUS_PAGE_FAULT_COPY_ON_WRITE, ERROR_PAGE_FAULT_COPY_ON_WRITE); + cmp2(STATUS_PAGE_FAULT_GUARD_PAGE, ERROR_PAGE_FAULT_GUARD_PAGE); + cmp2(STATUS_PAGE_FAULT_PAGING_FILE, ERROR_PAGE_FAULT_PAGING_FILE); + cmp2(STATUS_CACHE_PAGE_LOCKED, ERROR_CACHE_PAGE_LOCKED); + cmp2(STATUS_PAGEFILE_CREATE_FAILED, ERROR_PAGEFILE_CREATE_FAILED); + cmp2(STATUS_NO_PAGEFILE, ERROR_NO_PAGEFILE); cmp(STATUS_COMMITMENT_LIMIT, ERROR_COMMITMENT_LIMIT); + cmp2(STATUS_COMMITMENT_MINIMUM, ERROR_COMMITMENT_MINIMUM); cmp(STATUS_SECTION_TOO_BIG, ERROR_NOT_ENOUGH_MEMORY); + cmp2(STATUS_SEGMENT_NOTIFICATION, ERROR_SEGMENT_NOTIFICATION); cmp(RPC_NT_SS_IN_NULL_CONTEXT, ERROR_INVALID_HANDLE); cmp(RPC_NT_INVALID_BINDING, ERROR_INVALID_HANDLE); cmp(STATUS_INVALID_HANDLE, ERROR_INVALID_HANDLE); @@ -195,6 +226,7 @@ cmp(STATUS_NOT_COMMITTED, ERROR_INVALID_ADDRESS); cmp(STATUS_PARTIAL_COPY, ERROR_PARTIAL_COPY); cmp3(STATUS_LPC_REPLY_LOST, ERROR_CONNECTION_ABORTED, ERROR_INTERNAL_ERROR); + cmp2(STATUS_INVALID_VARIANT, ERROR_INVALID_VARIANT); cmp(STATUS_INVALID_PARAMETER, ERROR_INVALID_PARAMETER); cmp(STATUS_INVALID_PARAMETER_1, ERROR_INVALID_PARAMETER); cmp(STATUS_INVALID_PARAMETER_2, ERROR_INVALID_PARAMETER); @@ -219,6 +251,7 @@ cmp(STATUS_NO_SUCH_FILE, ERROR_FILE_NOT_FOUND); cmp(STATUS_INVALID_DEVICE_REQUEST, ERROR_INVALID_FUNCTION); cmp2(STATUS_VOLUME_NOT_UPGRADED, ERROR_INVALID_FUNCTION); + cmp2(STATUS_CONVERT_TO_LARGE, ERROR_CONVERT_TO_LARGE); cmp(STATUS_END_OF_FILE, ERROR_HANDLE_EOF); cmp(STATUS_FILE_FORCED_CLOSED, ERROR_HANDLE_EOF); cmp(STATUS_WRONG_VOLUME, ERROR_WRONG_DISK); @@ -225,13 +258,19 @@ cmp(STATUS_NO_MEDIA, ERROR_NO_MEDIA_IN_DRIVE); cmp(STATUS_NO_MEDIA_IN_DEVICE, ERROR_NOT_READY); cmp2(STATUS_VOLUME_DISMOUNTED, ERROR_NOT_READY); + cmp2(STATUS_VOLUME_MOUNTED, ERROR_VOLUME_MOUNTED); + cmp2(STATUS_MOUNT_POINT_NOT_RESOLVED, ERROR_MOUNT_POINT_NOT_RESOLVED); cmp(STATUS_NONEXISTENT_SECTOR, ERROR_SECTOR_NOT_FOUND); cmp(STATUS_WORKING_SET_QUOTA, ERROR_WORKING_SET_QUOTA); cmp(STATUS_NO_MEMORY, ERROR_NOT_ENOUGH_MEMORY); cmp(STATUS_CONFLICTING_ADDRESSES, ERROR_INVALID_ADDRESS); cmp(STATUS_INVALID_SYSTEM_SERVICE, ERROR_INVALID_FUNCTION); + cmp2(STATUS_THREAD_WAS_SUSPENDED, ERROR_THREAD_WAS_SUSPENDED); + cmp2(STATUS_TOO_MANY_THREADS, ERROR_TOO_MANY_THREADS); + cmp2(STATUS_THREAD_NOT_IN_PROCESS, ERROR_THREAD_NOT_IN_PROCESS); cmp(STATUS_THREAD_IS_TERMINATING, ERROR_ACCESS_DENIED); cmp(STATUS_PROCESS_IS_TERMINATING, ERROR_ACCESS_DENIED); + cmp2(STATUS_SYSTEM_PROCESS_TERMINATED, ERROR_SYSTEM_PROCESS_TERMINATED); cmp(STATUS_INVALID_LOCK_SEQUENCE, ERROR_ACCESS_DENIED); cmp(STATUS_INVALID_VIEW_SIZE, ERROR_ACCESS_DENIED); cmp(STATUS_ALREADY_COMMITTED, ERROR_ACCESS_DENIED); @@ -273,12 +312,16 @@ cmp(STATUS_BUFFER_TOO_SMALL, ERROR_INSUFFICIENT_BUFFER); cmp(STATUS_UNABLE_TO_DECOMMIT_VM, ERROR_INVALID_ADDRESS); cmp(STATUS_DISK_CORRUPT_ERROR, ERROR_DISK_CORRUPT); + cmp2(STATUS_FT_READ_RECOVERY_FROM_BACKUP, ERROR_FT_READ_RECOVERY_FROM_BACKUP); + cmp2(STATUS_FT_WRITE_RECOVERY, ERROR_FT_WRITE_RECOVERY); cmp(STATUS_FT_MISSING_MEMBER, ERROR_IO_DEVICE); cmp(STATUS_FT_ORPHANING, ERROR_IO_DEVICE); + cmp2(STATUS_BACKUP_CONTROLLER, ERROR_BACKUP_CONTROLLER); cmp(STATUS_VARIABLE_NOT_FOUND, ERROR_ENVVAR_NOT_FOUND); cmp(STATUS_OBJECT_NAME_INVALID, ERROR_INVALID_NAME); cmp(STATUS_OBJECT_NAME_NOT_FOUND, ERROR_FILE_NOT_FOUND); cmp(STATUS_OBJECT_NAME_COLLISION, ERROR_ALREADY_EXISTS); + cmp2(STATUS_OBJECT_NAME_EXISTS, ERROR_OBJECT_NAME_EXISTS); cmp(STATUS_OBJECT_PATH_INVALID, ERROR_BAD_PATHNAME); cmp(STATUS_OBJECT_PATH_NOT_FOUND, ERROR_PATH_NOT_FOUND); cmp(STATUS_DFS_EXIT_PATH_FOUND, ERROR_PATH_NOT_FOUND); @@ -288,14 +331,19 @@ cmp(STATUS_DATA_OVERRUN, ERROR_IO_DEVICE); cmp(STATUS_DATA_LATE_ERROR, ERROR_IO_DEVICE); cmp(STATUS_DATA_ERROR, ERROR_CRC); + cmp2(STATUS_DATA_NOT_ACCEPTED, ERROR_DATA_NOT_ACCEPTED); + cmp2(STATUS_LOST_WRITEBEHIND_DATA, ERROR_LOST_WRITEBEHIND_DATA); cmp(STATUS_CRC_ERROR, ERROR_CRC); cmp(STATUS_SHARING_VIOLATION, ERROR_SHARING_VIOLATION); cmp(STATUS_QUOTA_EXCEEDED, ERROR_NOT_ENOUGH_QUOTA); + cmp2(STATUS_FS_DRIVER_REQUIRED, ERROR_FS_DRIVER_REQUIRED); cmp(STATUS_MUTANT_NOT_OWNED, ERROR_NOT_OWNER); + cmp2(STATUS_MUTANT_LIMIT_EXCEEDED, ERROR_MUTANT_LIMIT_EXCEEDED); cmp(STATUS_SEMAPHORE_LIMIT_EXCEEDED, ERROR_TOO_MANY_POSTS); cmp(STATUS_DISK_FULL, ERROR_DISK_FULL); cmp(STATUS_LOCK_NOT_GRANTED, ERROR_LOCK_VIOLATION); cmp(STATUS_FILE_LOCK_CONFLICT, ERROR_LOCK_VIOLATION); + cmp2(STATUS_NOT_TINY_STREAM, ERROR_NOT_TINY_STREAM); cmp(STATUS_NOT_A_DIRECTORY, ERROR_DIRECTORY); cmp2(STATUS_CANNOT_MAKE, ERROR_CANNOT_MAKE); cmp(STATUS_UNKNOWN_REVISION, ERROR_UNKNOWN_REVISION); @@ -322,6 +370,9 @@ cmp(STATUS_PASSWORD_RESTRICTION, ERROR_PASSWORD_RESTRICTION); cmp(STATUS_PASSWORD_EXPIRED, ERROR_PASSWORD_EXPIRED); cmp(STATUS_PASSWORD_MUST_CHANGE, ERROR_PASSWORD_MUST_CHANGE); + cmp2(STATUS_PWD_TOO_SHORT, ERROR_PWD_TOO_SHORT); + cmp2(STATUS_PWD_TOO_RECENT, ERROR_PWD_TOO_RECENT); + cmp2(STATUS_PWD_HISTORY_CONFLICT, ERROR_PWD_HISTORY_CONFLICT); cmp(STATUS_ACCOUNT_DISABLED, ERROR_ACCOUNT_DISABLED); cmp(STATUS_ACCOUNT_LOCKED_OUT, ERROR_ACCOUNT_LOCKED_OUT); cmp(STATUS_NONE_MAPPED, ERROR_NONE_MAPPED); @@ -332,6 +383,7 @@ cmp(STATUS_INVALID_SID, ERROR_INVALID_SID); cmp(STATUS_INVALID_SECURITY_DESCR, ERROR_INVALID_SECURITY_DESCR); cmp(STATUS_PROCEDURE_NOT_FOUND, ERROR_PROC_NOT_FOUND); + cmp2(STATUS_VDM_HARD_ERROR, ERROR_VDM_HARD_ERROR); cmp2(STATUS_INVALID_LDT_SIZE, ERROR_INVALID_LDT_SIZE); cmp2(STATUS_INVALID_LDT_OFFSET, ERROR_INVALID_LDT_OFFSET); cmp2(STATUS_INVALID_LDT_DESCRIPTOR, ERROR_INVALID_LDT_DESCRIPTOR); @@ -349,11 +401,14 @@ cmp2(STATUS_INVALID_IMAGE_WIN_64, ERROR_BAD_EXE_FORMAT); cmp(STATUS_NO_TOKEN, ERROR_NO_TOKEN); cmp(STATUS_RANGE_NOT_LOCKED, ERROR_NOT_LOCKED); + cmp2(STATUS_RANGE_LIST_CONFLICT, ERROR_RANGE_LIST_CONFLICT); + cmp2(STATUS_RANGE_NOT_FOUND, ERROR_RANGE_NOT_FOUND); cmp(STATUS_SERVER_DISABLED, ERROR_SERVER_DISABLED); cmp(STATUS_SERVER_NOT_DISABLED, ERROR_SERVER_NOT_DISABLED); cmp(STATUS_INVALID_ID_AUTHORITY, ERROR_INVALID_ID_AUTHORITY); cmp(STATUS_ALLOTTED_SPACE_EXCEEDED, ERROR_ALLOTTED_SPACE_EXCEEDED); cmp(STATUS_TOO_MANY_PAGING_FILES, ERROR_NOT_ENOUGH_MEMORY); + cmp2(STATUS_RESOURCE_REQUIREMENTS_CHANGED, ERROR_RESOURCE_REQUIREMENTS_CHANGED); cmp(STATUS_INSUFFICIENT_RESOURCES, ERROR_NO_SYSTEM_RESOURCES); cmp(STATUS_INSUFF_SERVER_RESOURCES, ERROR_NOT_ENOUGH_SERVER_MEMORY); cmp(STATUS_FILE_INVALID, ERROR_FILE_INVALID); @@ -365,12 +420,17 @@ cmp(STATUS_DEVICE_NOT_READY, ERROR_NOT_READY); cmp3(STATUS_DEVICE_NOT_CONNECTED, ERROR_DEVICE_NOT_CONNECTED, ERROR_NOT_READY); cmp(STATUS_DEVICE_POWER_FAILURE, ERROR_NOT_READY); + cmp2(STATUS_INSUFFICIENT_POWER, ERROR_INSUFFICIENT_POWER); + cmp2(STATUS_DRIVER_FAILED_SLEEP, ERROR_DRIVER_FAILED_SLEEP); cmp2(STATUS_NOT_FOUND, ERROR_NOT_FOUND); cmp2(STATUS_NO_MATCH, ERROR_NO_MATCH); + cmp2(STATUS_NO_MORE_MATCHES, ERROR_NO_MORE_MATCHES); cmp2(STATUS_PROPSET_NOT_FOUND, ERROR_SET_NOT_FOUND); + cmp2(STATUS_FOUND_OUT_OF_SCOPE, ERROR_FOUND_OUT_OF_SCOPE); cmp(STATUS_DEVICE_BUSY, ERROR_BUSY); cmp(STATUS_FREE_VM_NOT_AT_BASE, ERROR_INVALID_ADDRESS); cmp(STATUS_MEMORY_NOT_ALLOCATED, ERROR_INVALID_ADDRESS); + cmp2(STATUS_ALLOCATE_BUCKET, ERROR_ALLOCATE_BUCKET); cmp(STATUS_NOT_SAME_DEVICE, ERROR_NOT_SAME_DEVICE); cmp(STATUS_NOT_SUPPORTED, ERROR_NOT_SUPPORTED); cmp(STATUS_REMOTE_NOT_LISTENING, ERROR_REM_NOT_LIST); @@ -381,6 +441,7 @@ cmp(STATUS_DEVICE_DOES_NOT_EXIST, ERROR_DEV_NOT_EXIST); cmp(STATUS_TOO_MANY_COMMANDS, ERROR_TOO_MANY_CMDS); cmp(STATUS_ADAPTER_HARDWARE_ERROR, ERROR_ADAP_HDW_ERR); + cmp2(STATUS_BIOS_FAILED_TO_CONNECT_INTERRUPT,ERROR_BIOS_FAILED_TO_CONNECT_INTERRUPT); cmp(STATUS_REDIRECTOR_NOT_STARTED, ERROR_PATH_NOT_FOUND); cmp(STATUS_INVALID_EA_NAME, ERROR_INVALID_EA_NAME); cmp(STATUS_EA_LIST_INCONSISTENT, ERROR_EA_LIST_INCONSISTENT); @@ -391,6 +452,8 @@ cmp(STATUS_EA_CORRUPT_ERROR, ERROR_FILE_CORRUPT); cmp(STATUS_NONEXISTENT_EA_ENTRY, ERROR_FILE_CORRUPT); cmp(STATUS_NO_EAS_ON_FILE, ERROR_FILE_CORRUPT); + cmp2(STATUS_REPARSE, ERROR_REPARSE); + cmp2(STATUS_REPARSE_OBJECT, ERROR_REPARSE_OBJECT); cmp2(STATUS_NOT_A_REPARSE_POINT, ERROR_NOT_A_REPARSE_POINT); cmp4(STATUS_IO_REPARSE_TAG_INVALID, ERROR_REPARSE_TAG_INVALID, ERROR_INVALID_PARAMETER); cmp4(STATUS_IO_REPARSE_TAG_MISMATCH, ERROR_REPARSE_TAG_MISMATCH, ERROR_INVALID_PARAMETER); @@ -406,6 +469,7 @@ cmp2(STATUS_JOURNAL_DELETE_IN_PROGRESS, ERROR_JOURNAL_DELETE_IN_PROGRESS); cmp2(STATUS_JOURNAL_NOT_ACTIVE, ERROR_JOURNAL_NOT_ACTIVE); cmp2(STATUS_JOURNAL_ENTRY_DELETED, ERROR_JOURNAL_ENTRY_DELETED); + cmp2(STATUS_PRIMARY_TRANSPORT_CONNECT_FAILED,ERROR_PRIMARY_TRANSPORT_CONNECT_FAILED); cmp(STATUS_INVALID_NETWORK_RESPONSE, ERROR_BAD_NET_RESP); cmp(STATUS_USER_SESSION_DELETED, ERROR_UNEXP_NET_ERR); cmp(STATUS_UNEXPECTED_NETWORK_ERROR, ERROR_UNEXP_NET_ERR); @@ -423,6 +487,7 @@ cmp(STATUS_TOO_MANY_NODES, ERROR_TOO_MANY_NAMES); cmp(STATUS_TOO_MANY_SESSIONS, ERROR_TOO_MANY_SESS); cmp(STATUS_SHARING_PAUSED, ERROR_SHARING_PAUSED); + cmp2(STATUS_CANT_ENABLE_DENY_ONLY, ERROR_CANT_ENABLE_DENY_ONLY); cmp(STATUS_REQUEST_NOT_ACCEPTED, ERROR_REQ_NOT_ACCEP); cmp(STATUS_REDIRECTOR_PAUSED, ERROR_REDIR_PAUSED); cmp(STATUS_NET_WRITE_FAULT, ERROR_NET_WRITE_FAULT); @@ -452,6 +517,7 @@ cmp(STATUS_END_OF_MEDIA, ERROR_END_OF_MEDIA); cmp(STATUS_EOM_OVERFLOW, ERROR_EOM_OVERFLOW); cmp(STATUS_BEGINNING_OF_MEDIA, ERROR_BEGINNING_OF_MEDIA); + cmp2(STATUS_MEDIA_CHECK, ERROR_MEDIA_CHECK); cmp(STATUS_MEDIA_CHANGED, ERROR_MEDIA_CHANGED); cmp(STATUS_BUS_RESET, ERROR_BUS_RESET); cmp(STATUS_FILEMARK_DETECTED, ERROR_FILEMARK_DETECTED); @@ -462,12 +528,32 @@ cmp(STATUS_DEVICE_NOT_PARTITIONED, ERROR_DEVICE_NOT_PARTITIONED); cmp(STATUS_UNABLE_TO_LOCK_MEDIA, ERROR_UNABLE_TO_LOCK_MEDIA); cmp(STATUS_UNABLE_TO_UNLOAD_MEDIA, ERROR_UNABLE_TO_UNLOAD_MEDIA); + cmp2(STATUS_ILLEGAL_CHARACTER, ERROR_ILLEGAL_CHARACTER); cmp(STATUS_UNMAPPABLE_CHARACTER, ERROR_NO_UNICODE_TRANSLATION); + cmp2(STATUS_UNDEFINED_CHARACTER, ERROR_UNDEFINED_CHARACTER); + cmp2(STATUS_TRANSLATION_COMPLETE, ERROR_TRANSLATION_COMPLETE); cmp(STATUS_NOT_ALL_ASSIGNED, ERROR_NOT_ALL_ASSIGNED); cmp(STATUS_SOME_NOT_MAPPED, ERROR_SOME_NOT_MAPPED); cmp(STATUS_NO_QUOTAS_FOR_ACCOUNT, ERROR_NO_QUOTAS_FOR_ACCOUNT); + cmp2(STATUS_QUOTA_LIST_INCONSISTENT, ERROR_QUOTA_LIST_INCONSISTENT); cmp(STATUS_LOCAL_USER_SESSION_KEY, ERROR_LOCAL_USER_SESSION_KEY); cmp(STATUS_NULL_LM_PASSWORD, ERROR_NULL_LM_PASSWORD); + cmp2(STATUS_SYNCHRONIZATION_REQUIRED, ERROR_SYNCHRONIZATION_REQUIRED); + cmp2(STATUS_WAKE_SYSTEM_DEBUGGER, ERROR_WAKE_SYSTEM_DEBUGGER); + cmp2(DBG_EXCEPTION_HANDLED, ERROR_DBG_EXCEPTION_HANDLED); + cmp2(DBG_CONTINUE, ERROR_DBG_CONTINUE); + cmp2(DBG_TERMINATE_THREAD, ERROR_DBG_TERMINATE_THREAD); + cmp2(DBG_TERMINATE_PROCESS, ERROR_DBG_TERMINATE_PROCESS); + cmp2(DBG_CONTROL_C, ERROR_DBG_CONTROL_C); + cmp2(DBG_PRINTEXCEPTION_C, ERROR_DBG_PRINTEXCEPTION_C); + cmp2(DBG_RIPEXCEPTION, ERROR_DBG_RIPEXCEPTION); + cmp2(DBG_CONTROL_BREAK, ERROR_DBG_CONTROL_BREAK); + cmp2(DBG_COMMAND_EXCEPTION, ERROR_DBG_COMMAND_EXCEPTION); + cmp2(DBG_EXCEPTION_NOT_HANDLED, ERROR_DBG_EXCEPTION_NOT_HANDLED); + cmp2(STATUS_DEBUG_ATTACH_FAILED, ERROR_DEBUG_ATTACH_FAILED); + cmp2(STATUS_VALIDATE_CONTINUE, ERROR_VALIDATE_CONTINUE); + cmp2(STATUS_EXTRANEOUS_INFORMATION, ERROR_EXTRANEOUS_INFORMATION); + cmp2(STATUS_GUID_SUBSTITUTION_MADE, ERROR_GUID_SUBSTITUTION_MADE); cmp2(STATUS_IMAGE_MACHINE_TYPE_MISMATCH, ERROR_IMAGE_MACHINE_TYPE_MISMATCH); cmp2(STATUS_RECEIVE_PARTIAL, ERROR_RECEIVE_PARTIAL); cmp2(STATUS_RECEIVE_EXPEDITED, ERROR_RECEIVE_EXPEDITED); @@ -485,9 +571,30 @@ cmp2(STATUS_IMAGE_MACHINE_TYPE_MISMATCH_EXE, ERROR_IMAGE_MACHINE_TYPE_MISMATCH_EXE); cmp2(STATUS_NO_YIELD_PERFORMED, ERROR_NO_YIELD_PERFORMED); cmp2(STATUS_TIMER_RESUME_IGNORED, ERROR_TIMER_RESUME_IGNORED); + cmp2(STATUS_TIMER_RESOLUTION_NOT_SET, ERROR_TIMER_RESOLUTION_NOT_SET); + cmp2(STATUS_ARBITRATION_UNHANDLED, ERROR_ARBITRATION_UNHANDLED); + cmp2(STATUS_CARDBUS_NOT_SUPPORTED, ERROR_CARDBUS_NOT_SUPPORTED); + cmp2(STATUS_MP_PROCESSOR_MISMATCH, ERROR_MP_PROCESSOR_MISMATCH); + cmp2(STATUS_HIBERNATED, ERROR_HIBERNATED); + cmp2(STATUS_RESUME_HIBERNATION, ERROR_RESUME_HIBERNATION); + cmp2(STATUS_FIRMWARE_UPDATED, ERROR_FIRMWARE_UPDATED); + cmp2(STATUS_WAKE_SYSTEM, ERROR_WAKE_SYSTEM); + cmp2(STATUS_WAIT_1, ERROR_WAIT_1); + cmp2(STATUS_WAIT_2, ERROR_WAIT_2); + cmp2(STATUS_WAIT_3, ERROR_WAIT_3); + cmp2(STATUS_WAIT_63, ERROR_WAIT_63); + cmp2(STATUS_ABANDONED_WAIT_0, ERROR_WAIT_NO_CHILDREN); + cmp2(STATUS_ABANDONED_WAIT_63, ERROR_ABANDONED_WAIT_63); + cmp2(STATUS_USER_APC, ERROR_USER_APC); + cmp2(STATUS_KERNEL_APC, ERROR_KERNEL_APC); + cmp2(STATUS_ALERTED, ERROR_ALERTED); + cmp2(STATUS_NOTIFY_CLEANUP, ERROR_NOTIFY_CLEANUP); + cmp2(STATUS_NO_CALLBACK_ACTIVE, ERROR_NO_CALLBACK_ACTIVE); + cmp4(STATUS_NOINTERFACE, ERROR_NOINTERFACE, E_NOINTERFACE); cmp(STATUS_BAD_INHERITANCE_ACL, ERROR_BAD_INHERITANCE_ACL); cmp(STATUS_INVALID_GROUP_ATTRIBUTES, ERROR_INVALID_GROUP_ATTRIBUTES); cmp(STATUS_BAD_IMPERSONATION_LEVEL, ERROR_BAD_IMPERSONATION_LEVEL); + cmp2(STATUS_ELEVATION_REQUIRED, ERROR_ELEVATION_REQUIRED); cmp(STATUS_CANT_OPEN_ANONYMOUS, ERROR_CANT_OPEN_ANONYMOUS); cmp(STATUS_BAD_VALIDATION_CLASS, ERROR_BAD_VALIDATION_CLASS); cmp(STATUS_BAD_TOKEN_TYPE, ERROR_BAD_TOKEN_TYPE); @@ -502,6 +609,7 @@ cmp(STATUS_DOMAIN_LIMIT_EXCEEDED, ERROR_DOMAIN_LIMIT_EXCEEDED); cmp2(STATUS_OPLOCK_NOT_GRANTED, ERROR_OPLOCK_NOT_GRANTED); cmp2(STATUS_INVALID_OPLOCK_PROTOCOL, ERROR_INVALID_OPLOCK_PROTOCOL); + cmp2(STATUS_OPLOCK_BREAK_IN_PROGRESS, ERROR_OPLOCK_BREAK_IN_PROGRESS); cmp(STATUS_INTERNAL_DB_CORRUPTION, ERROR_INTERNAL_DB_CORRUPTION); cmp(STATUS_INTERNAL_ERROR, ERROR_INTERNAL_ERROR); cmp(STATUS_GENERIC_NOT_MAPPED, ERROR_GENERIC_NOT_MAPPED); @@ -512,7 +620,12 @@ cmp(STATUS_BAD_LOGON_SESSION_STATE, ERROR_BAD_LOGON_SESSION_STATE); cmp(STATUS_LOGON_SESSION_COLLISION, ERROR_LOGON_SESSION_COLLISION); cmp(STATUS_INVALID_LOGON_TYPE, ERROR_INVALID_LOGON_TYPE); + cmp2(STATUS_LOGON_SERVER_CONFLICT, ERROR_LOGON_SERVER_CONFLICT); + cmp2(STATUS_SERVER_SID_MISMATCH, ERROR_SERVER_SID_MISMATCH); + cmp2(STATUS_RXACT_STATE_CREATED, ERROR_RXACT_STATE_CREATED); cmp(STATUS_RXACT_INVALID_STATE, ERROR_RXACT_INVALID_STATE); + cmp2(STATUS_RXACT_COMMITTED, ERROR_RXACT_COMMITTED); + cmp2(STATUS_RXACT_COMMIT_NECESSARY, ERROR_RXACT_COMMIT_NECESSARY); cmp(STATUS_RXACT_COMMIT_FAILURE, ERROR_RXACT_COMMIT_FAILURE); cmp(STATUS_SPECIAL_ACCOUNT, ERROR_SPECIAL_ACCOUNT); cmp(STATUS_SPECIAL_USER, ERROR_SPECIAL_USER); @@ -532,6 +645,8 @@ cmp(STATUS_NO_SUCH_MEMBER, ERROR_NO_SUCH_MEMBER); cmp(STATUS_INVALID_MEMBER, ERROR_INVALID_MEMBER); cmp(STATUS_TOO_MANY_SIDS, ERROR_TOO_MANY_SIDS); + cmp2(STATUS_ALL_SIDS_FILTERED, ERROR_ALL_SIDS_FILTERED); + cmp2(STATUS_INSUFFICIENT_LOGON_INFO, ERROR_INSUFFICIENT_LOGON_INFO); cmp(STATUS_LM_CROSS_ENCRYPTION_REQUIRED, ERROR_LM_CROSS_ENCRYPTION_REQUIRED); cmp(STATUS_MESSAGE_NOT_FOUND, ERROR_MR_MID_NOT_FOUND); cmp2(STATUS_CONTROL_C_EXIT, ERROR_CONTROL_C_EXIT); @@ -542,12 +657,20 @@ cmp(STATUS_LINK_TIMEOUT, ERROR_UNEXP_NET_ERR); cmp(STATUS_INVALID_CONNECTION, ERROR_UNEXP_NET_ERR); cmp(STATUS_INVALID_ADDRESS, ERROR_UNEXP_NET_ERR); + cmp2(STATUS_IP_ADDRESS_CONFLICT1, ERROR_IP_ADDRESS_CONFLICT1); + cmp2(STATUS_IP_ADDRESS_CONFLICT2, ERROR_IP_ADDRESS_CONFLICT2); cmp2(STATUS_MISSING_SYSTEMFILE, ERROR_MISSING_SYSTEMFILE); - cmp2(STATUS_PAGEFILE_CREATE_FAILED, ERROR_PAGEFILE_CREATE_FAILED); + cmp2(STATUS_CORRUPT_SYSTEM_FILE, ERROR_CORRUPT_SYSTEM_FILE); + cmp2(STATUS_SYSTEM_IMAGE_BAD_SIGNATURE, ERROR_SYSTEM_IMAGE_BAD_SIGNATURE); + cmp2(STATUS_CRASH_DUMP, ERROR_CRASH_DUMP); + cmp2(STATUS_LONGJUMP, ERROR_LONGJUMP); + cmp2(STATUS_UNWIND_CONSOLIDATE, ERROR_UNWIND_CONSOLIDATE); cmp2(STATUS_UNHANDLED_EXCEPTION, ERROR_UNHANDLED_EXCEPTION); + cmp2(STATUS_MCA_OCCURED, ERROR_MCA_OCCURED); cmp2(STATUS_APP_INIT_FAILURE, ERROR_APP_INIT_FAILURE); - cmp2(STATUS_NO_PAGEFILE, ERROR_NO_PAGEFILE); cmp2(STATUS_ILLEGAL_FLOAT_CONTEXT, ERROR_ILLEGAL_FLOAT_CONTEXT); + cmp2(STATUS_FLOAT_MULTIPLE_FAULTS, ERROR_FLOAT_MULTIPLE_FAULTS); + cmp2(STATUS_FLOAT_MULTIPLE_TRAPS, ERROR_FLOAT_MULTIPLE_TRAPS); cmp2(STATUS_NO_EVENT_PAIR, ERROR_NO_EVENT_PAIR); cmp2(STATUS_DOMAIN_CTRLR_CONFIG_ERROR, ERROR_DOMAIN_CTRLR_CONFIG_ERROR); cmp(STATUS_IO_DEVICE_ERROR, ERROR_IO_DEVICE); @@ -555,6 +678,8 @@ cmp(STATUS_DRIVER_INTERNAL_ERROR, ERROR_IO_DEVICE); cmp(STATUS_INVALID_DEVICE_STATE, ERROR_BAD_COMMAND); cmp(STATUS_DEVICE_CONFIGURATION_ERROR, ERROR_INVALID_PARAMETER); + cmp2(STATUS_DEVICE_ENUMERATION_ERROR, ERROR_DEVICE_ENUMERATION_ERROR); + cmp2(STATUS_INVALID_DEVICE_OBJECT_PARAMETER, ERROR_INVALID_DEVICE_OBJECT_PARAMETER); cmp2(STATUS_SOURCE_ELEMENT_EMPTY, ERROR_SOURCE_ELEMENT_EMPTY); cmp2(STATUS_DESTINATION_ELEMENT_FULL, ERROR_DESTINATION_ELEMENT_FULL); cmp2(STATUS_ILLEGAL_ELEMENT_ADDRESS, ERROR_ILLEGAL_ELEMENT_ADDRESS); @@ -575,7 +700,10 @@ cmp2(STATUS_NOT_EXPORT_FORMAT, ERROR_NOT_EXPORT_FORMAT); cmp2(STATUS_FILE_ENCRYPTED, ERROR_FILE_ENCRYPTED); cmp2(STATUS_EFS_ALG_BLOB_TOO_BIG, ERROR_EFS_ALG_BLOB_TOO_BIG); + cmp2(STATUS_BUFFER_ALL_ZEROS, ERROR_BUFFER_ALL_ZEROS); cmp(STATUS_INVALID_USER_BUFFER, ERROR_INVALID_USER_BUFFER); + cmp2(STATUS_BAD_COMPRESSION_BUFFER, ERROR_BAD_COMPRESSION_BUFFER); + cmp2(STATUS_UNSUPPORTED_COMPRESSION, ERROR_UNSUPPORTED_COMPRESSION); cmp(STATUS_SERIAL_NO_DEVICE_INITED, ERROR_SERIAL_NO_DEVICE); cmp(STATUS_SHARED_IRQ_BUSY, ERROR_IRQ_BUSY); cmp(STATUS_SERIAL_MORE_WRITES, ERROR_MORE_WRITES); @@ -584,6 +712,7 @@ cmp(STATUS_FLOPPY_WRONG_CYLINDER, ERROR_FLOPPY_WRONG_CYLINDER); cmp(STATUS_FLOPPY_UNKNOWN_ERROR, ERROR_FLOPPY_UNKNOWN_ERROR); cmp(STATUS_FLOPPY_BAD_REGISTERS, ERROR_FLOPPY_BAD_REGISTERS); + cmp2(STATUS_FLOPPY_VOLUME, ERROR_FLOPPY_VOLUME); cmp(STATUS_DISK_RECALIBRATE_FAILED, ERROR_DISK_RECALIBRATE_FAILED); cmp(STATUS_DISK_OPERATION_FAILED, ERROR_DISK_OPERATION_FAILED); cmp(STATUS_DISK_RESET_FAILED, ERROR_DISK_RESET_FAILED); @@ -609,8 +738,14 @@ cmp(STATUS_TRANSACTION_INVALID_TYPE, ERROR_UNEXP_NET_ERR); cmp(STATUS_NOT_SERVER_SESSION, ERROR_NOT_SUPPORTED); cmp(STATUS_NOT_CLIENT_SESSION, ERROR_NOT_SUPPORTED); + cmp2(STATUS_CLIENT_SERVER_PARAMETERS_INVALID,ERROR_CLIENT_SERVER_PARAMETERS_INVALID); cmp(STATUS_USER_MAPPED_FILE, ERROR_USER_MAPPED_FILE); + cmp2(STATUS_INVALID_HW_PROFILE, ERROR_INVALID_HW_PROFILE); cmp(STATUS_PLUGPLAY_NO_DEVICE, ERROR_SERVICE_DISABLED); + cmp2(STATUS_PLUGPLAY_QUERY_VETOED, ERROR_PLUGPLAY_QUERY_VETOED); + cmp2(STATUS_INVALID_PLUGPLAY_DEVICE_PATH, ERROR_INVALID_PLUGPLAY_DEVICE_PATH); + cmp2(STATUS_PNP_RESTART_ENUMERATION, ERROR_PNP_RESTART_ENUMERATION); + cmp2(STATUS_PNP_REBOOT_REQUIRED, ERROR_PNP_REBOOT_REQUIRED); cmp2(STATUS_WMI_GUID_NOT_FOUND, ERROR_WMI_GUID_NOT_FOUND); cmp2(STATUS_WMI_INSTANCE_NOT_FOUND, ERROR_WMI_INSTANCE_NOT_FOUND); cmp2(STATUS_WMI_ITEMID_NOT_FOUND, ERROR_WMI_ITEMID_NOT_FOUND); @@ -815,6 +950,7 @@ cmp2(CRYPT_E_REVOCATION_OFFLINE, ERROR_MUTUAL_AUTH_FAILED); cmp2(STATUS_SHUTDOWN_IN_PROGRESS, ERROR_SHUTDOWN_IN_PROGRESS); cmp2(STATUS_SERVER_SHUTDOWN_IN_PROGRESS, ERROR_SERVER_SHUTDOWN_IN_PROGRESS); + cmp2(STATUS_SYSTEM_SHUTDOWN, ERROR_SYSTEM_SHUTDOWN); cmp4(STATUS_DS_MEMBERSHIP_EVALUATED_LOCALLY, ERROR_DS_MEMBERSHIP_EVALUATED_LOCALLY, 1922); cmp4(STATUS_DS_NO_ATTRIBUTE_OR_VALUE, ERROR_DS_NO_ATTRIBUTE_OR_VALUE, 1923); cmp4(STATUS_DS_INVALID_ATTRIBUTE_SYNTAX, ERROR_DS_INVALID_ATTRIBUTE_SYNTAX, 1924); @@ -857,6 +993,7 @@ cmp2(STATUS_SAM_NEED_BOOTKEY_FLOPPY, ERROR_DS_SAM_NEED_BOOTKEY_FLOPPY); cmp2(STATUS_DS_INIT_FAILURE_CONSOLE, ERROR_DS_INIT_FAILURE_CONSOLE); cmp2(STATUS_DS_SAM_INIT_FAILURE_CONSOLE, ERROR_DS_SAM_INIT_FAILURE_CONSOLE); + cmp2(STATUS_DS_VERSION_CHECK_FAILURE, ERROR_DS_VERSION_CHECK_FAILURE); cmp2(STATUS_UNFINISHED_CONTEXT_DELETED, SEC_E_UNFINISHED_CONTEXT_DELETED); cmp2(STATUS_NO_TGT_REPLY, SEC_E_NO_TGT_REPLY); cmp2(STATUS_NO_IP_ADDRESSES, SEC_E_NO_IP_ADDRESSES); @@ -881,6 +1018,7 @@ cmp2(STATUS_NOT_SUPPORTED_ON_SBS, ERROR_NOT_SUPPORTED_ON_SBS); cmp2(STATUS_DRIVER_BLOCKED_CRITICAL, ERROR_DRIVER_BLOCKED); cmp2(STATUS_DRIVER_BLOCKED, ERROR_DRIVER_BLOCKED); + cmp2(STATUS_DRIVER_CANCEL_TIMEOUT, ERROR_DRIVER_CANCEL_TIMEOUT); cmp2(STATUS_PRENT4_MACHINE_ACCOUNT, ERROR_DS_MACHINE_ACCOUNT_CREATED_PRENT4); cmp2(STATUS_DS_AG_CANT_HAVE_UNIVERSAL_MEMBER,ERROR_DS_AG_CANT_HAVE_UNIVERSAL_MEMBER); cmp2(STATUS_DS_SHUTTING_DOWN, ERROR_DS_SHUTTING_DOWN); @@ -926,6 +1064,7 @@ cmp2(STATUS_CTX_SHADOW_ENDED_BY_MODE_CHANGE, ERROR_CTX_SHADOW_ENDED_BY_MODE_CHANGE); cmp2(STATUS_CTX_SHADOW_NOT_RUNNING, ERROR_CTX_SHADOW_NOT_RUNNING); cmp2(STATUS_LICENSE_VIOLATION, ERROR_CTX_LICENSE_NOT_AVAILABLE); + cmp2(STATUS_EVALUATION_EXPIRATION, ERROR_EVALUATION_EXPIRATION); cmp2(STATUS_NETWORK_SESSION_EXPIRED, ERROR_NO_USER_SESSION_KEY); cmp2(STATUS_FILES_OPEN, ERROR_OPEN_FILES); cmp2(STATUS_SXS_SECTION_NOT_FOUND, ERROR_SXS_SECTION_NOT_FOUND); @@ -968,6 +1107,7 @@ cmp2(STATUS_SXS_FILE_HASH_MISSING, ERROR_SXS_FILE_HASH_MISSING); cmp2(STATUS_REDIRECTOR_STARTED, ERROR_SERVICE_ALREADY_RUNNING); cmp2(STATUS_AUDITING_DISABLED, ERROR_AUDITING_DISABLED); + cmp2(STATUS_AUDIT_FAILED, ERROR_AUDIT_FAILED); cmp2(STATUS_CLUSTER_NODE_ALREADY_UP, ERROR_CLUSTER_NODE_ALREADY_UP); cmp2(STATUS_CLUSTER_NODE_ALREADY_DOWN, ERROR_CLUSTER_NODE_ALREADY_DOWN); cmp2(STATUS_CLUSTER_NETWORK_ALREADY_ONLINE, ERROR_CLUSTER_NETWORK_ALREADY_ONLINE); Index: modules/rostests/winetests/ntdll/exception.c =================================================================== --- modules/rostests/winetests/ntdll/exception.c (revision 70979) +++ modules/rostests/winetests/ntdll/exception.c (working copy) @@ -221,6 +221,11 @@ { { 0xf1, 0x90, 0xc3 }, /* icebp; nop; ret */ 1, 1, FALSE, STATUS_SINGLE_STEP, 0 }, + { { 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, /* mov $0xb8b8b8b8, %eax */ + 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, /* mov $0xb9b9b9b9, %ecx */ + 0xba, 0xba, 0xba, 0xba, 0xba, /* mov $0xbabababa, %edx */ + 0xcd, 0x2d, 0xc3 }, /* int $0x2d; ret */ + 17, 0, FALSE, STATUS_BREAKPOINT, 3, { 0xb8b8b8b8, 0xb9b9b9b9, 0xbabababa } }, }; static int got_exception; @@ -475,7 +480,7 @@ CONTEXT *context, EXCEPTION_REGISTRATION_RECORD **dispatcher ) { const struct exception *except = *(const struct exception **)(frame + 1); - unsigned int i, entry = except - exceptions; + unsigned int i, parameter_count, entry = except - exceptions; got_exception++; trace( "exception %u: %x flags:%x addr:%p\n", @@ -484,21 +489,24 @@ ok( rec->ExceptionCode == except->status || (except->alt_status != 0 && rec->ExceptionCode == except->alt_status), "%u: Wrong exception code %x/%x\n", entry, rec->ExceptionCode, except->status ); - ok( rec->ExceptionAddress == (char*)code_mem + except->offset, - "%u: Wrong exception address %p/%p\n", entry, - rec->ExceptionAddress, (char*)code_mem + except->offset ); + ok( context->Eip == (DWORD_PTR)code_mem + except->offset, + "%u: Unexpected eip %#x/%#lx\n", entry, + context->Eip, (DWORD_PTR)code_mem + except->offset ); + ok( rec->ExceptionAddress == (char*)context->Eip || + (rec->ExceptionCode == STATUS_BREAKPOINT && rec->ExceptionAddress == (char*)context->Eip + 1), + "%u: Unexpected exception address %p/%p\n", entry, + rec->ExceptionAddress, (char*)context->Eip ); - if (except->alt_status == 0 || rec->ExceptionCode != except->alt_status) - { - ok( rec->NumberParameters == except->nb_params, - "%u: Wrong number of parameters %u/%u\n", entry, rec->NumberParameters, except->nb_params ); - } + if (except->status == STATUS_BREAKPOINT && is_wow64) + parameter_count = 1; + else if (except->alt_status == 0 || rec->ExceptionCode != except->alt_status) + parameter_count = except->nb_params; else - { - ok( rec->NumberParameters == except->alt_nb_params, - "%u: Wrong number of parameters %u/%u\n", entry, rec->NumberParameters, except->nb_params ); - } + parameter_count = except->alt_nb_params; + ok( rec->NumberParameters == parameter_count, + "%u: Unexpected parameter count %u/%u\n", entry, rec->NumberParameters, parameter_count ); + /* Most CPUs (except Intel Core apparently) report a segment limit violation */ /* instead of page faults for accesses beyond 0xffffffff */ if (except->nb_params == 2 && except->params[1] >= 0xfffffffd) @@ -532,7 +540,7 @@ skip_params: /* don't handle exception if it's not the address we expected */ - if (rec->ExceptionAddress != (char*)code_mem + except->offset) return ExceptionContinueSearch; + if (context->Eip != (DWORD_PTR)code_mem + except->offset) return ExceptionContinueSearch; context->Eip += except->length; return ExceptionContinueExecution; @@ -941,6 +949,24 @@ } else if (stage == 7 || stage == 8) { + ok(de.u.Exception.ExceptionRecord.ExceptionCode == EXCEPTION_BREAKPOINT, + "expected EXCEPTION_BREAKPOINT, got %08x\n", de.u.Exception.ExceptionRecord.ExceptionCode); + ok((char *)ctx.Eip == (char *)code_mem_address + 0x1d, + "expected Eip = %p, got 0x%x\n", (char *)code_mem_address + 0x1d, ctx.Eip); + + if (stage == 8) continuestatus = DBG_EXCEPTION_NOT_HANDLED; + } + else if (stage == 9 || stage == 10) + { + ok(de.u.Exception.ExceptionRecord.ExceptionCode == EXCEPTION_BREAKPOINT, + "expected EXCEPTION_BREAKPOINT, got %08x\n", de.u.Exception.ExceptionRecord.ExceptionCode); + ok((char *)ctx.Eip == (char *)code_mem_address + 2, + "expected Eip = %p, got 0x%x\n", (char *)code_mem_address + 2, ctx.Eip); + + if (stage == 10) continuestatus = DBG_EXCEPTION_NOT_HANDLED; + } + else if (stage == 11 || stage == 12) + { ok(de.u.Exception.ExceptionRecord.ExceptionCode == EXCEPTION_INVALID_HANDLE, "unexpected exception code %08x, expected %08x\n", de.u.Exception.ExceptionRecord.ExceptionCode, EXCEPTION_INVALID_HANDLE); @@ -947,7 +973,7 @@ ok(de.u.Exception.ExceptionRecord.NumberParameters == 0, "unexpected number of parameters %d, expected 0\n", de.u.Exception.ExceptionRecord.NumberParameters); - if (stage == 8) continuestatus = DBG_EXCEPTION_NOT_HANDLED; + if (stage == 12) continuestatus = DBG_EXCEPTION_NOT_HANDLED; } else ok(FALSE, "unexpected stage %x\n", stage); @@ -1035,23 +1061,26 @@ context->Eip += 3; /* skip addps */ return ExceptionContinueExecution; } - - /* stage 2 - divide by zero fault */ - if( rec->ExceptionCode == EXCEPTION_ILLEGAL_INSTRUCTION) - skip("system doesn't support SIMD exceptions\n"); - else { - ok( rec->ExceptionCode == STATUS_FLOAT_MULTIPLE_TRAPS, - "exception code: %#x, should be %#x\n", - rec->ExceptionCode, STATUS_FLOAT_MULTIPLE_TRAPS); - ok( rec->NumberParameters == 1 || broken(is_wow64 && rec->NumberParameters == 2), - "# of params: %i, should be 1\n", - rec->NumberParameters); - if( rec->NumberParameters == 1 ) - ok( rec->ExceptionInformation[0] == 0, "param #1: %lx, should be 0\n", rec->ExceptionInformation[0]); + else if ( *stage == 2 || *stage == 3 ) { + /* stage 2 - divide by zero fault */ + /* stage 3 - invalid operation fault */ + if( rec->ExceptionCode == EXCEPTION_ILLEGAL_INSTRUCTION) + skip("system doesn't support SIMD exceptions\n"); + else { + ok( rec->ExceptionCode == STATUS_FLOAT_MULTIPLE_TRAPS, + "exception code: %#x, should be %#x\n", + rec->ExceptionCode, STATUS_FLOAT_MULTIPLE_TRAPS); + ok( rec->NumberParameters == 1 || broken(is_wow64 && rec->NumberParameters == 2), + "# of params: %i, should be 1\n", + rec->NumberParameters); + if( rec->NumberParameters == 1 ) + ok( rec->ExceptionInformation[0] == 0, "param #1: %lx, should be 0\n", rec->ExceptionInformation[0]); + } + context->Eip += 3; /* skip divps */ } + else + ok(FALSE, "unexpected stage %x\n", *stage); - context->Eip += 3; /* skip divps */ - return ExceptionContinueExecution; } @@ -1058,6 +1087,7 @@ static const BYTE simd_exception_test[] = { 0x83, 0xec, 0x4, /* sub $0x4, %esp */ 0x0f, 0xae, 0x1c, 0x24, /* stmxcsr (%esp) */ + 0x8b, 0x04, 0x24, /* mov (%esp),%eax * store mxcsr */ 0x66, 0x81, 0x24, 0x24, 0xff, 0xfd, /* andw $0xfdff,(%esp) * enable divide by */ 0x0f, 0xae, 0x14, 0x24, /* ldmxcsr (%esp) * zero exceptions */ 0x6a, 0x01, /* push $0x1 */ @@ -1068,12 +1098,27 @@ 0x0f, 0x57, 0xc0, /* xorps %xmm0,%xmm0 * clear divisor */ 0x0f, 0x5e, 0xc8, /* divps %xmm0,%xmm1 * generate fault */ 0x83, 0xc4, 0x10, /* add $0x10,%esp */ - 0x66, 0x81, 0x0c, 0x24, 0x00, 0x02, /* orw $0x200,(%esp) * disable exceptions */ + 0x89, 0x04, 0x24, /* mov %eax,(%esp) * restore to old mxcsr */ 0x0f, 0xae, 0x14, 0x24, /* ldmxcsr (%esp) */ 0x83, 0xc4, 0x04, /* add $0x4,%esp */ 0xc3, /* ret */ }; +static const BYTE simd_exception_test2[] = { + 0x83, 0xec, 0x4, /* sub $0x4, %esp */ + 0x0f, 0xae, 0x1c, 0x24, /* stmxcsr (%esp) */ + 0x8b, 0x04, 0x24, /* mov (%esp),%eax * store mxcsr */ + 0x66, 0x81, 0x24, 0x24, 0x7f, 0xff, /* andw $0xff7f,(%esp) * enable invalid */ + 0x0f, 0xae, 0x14, 0x24, /* ldmxcsr (%esp) * operation exceptions */ + 0x0f, 0x57, 0xc9, /* xorps %xmm1,%xmm1 * clear dividend */ + 0x0f, 0x57, 0xc0, /* xorps %xmm0,%xmm0 * clear divisor */ + 0x0f, 0x5e, 0xc8, /* divps %xmm0,%xmm1 * generate fault */ + 0x89, 0x04, 0x24, /* mov %eax,(%esp) * restore to old mxcsr */ + 0x0f, 0xae, 0x14, 0x24, /* ldmxcsr (%esp) */ + 0x83, 0xc4, 0x04, /* add $0x4,%esp */ + 0xc3, /* ret */ +}; + static const BYTE sse_check[] = { 0x0f, 0x58, 0xc8, /* addps %xmm0,%xmm1 */ 0xc3, /* ret */ @@ -1097,7 +1142,14 @@ got_exception = 0; run_exception_test(simd_fault_handler, &stage, simd_exception_test, sizeof(simd_exception_test), 0); - ok( got_exception == 1, "got exception: %i, should be 1\n", got_exception); + ok(got_exception == 1, "got exception: %i, should be 1\n", got_exception); + + /* generate a SIMD exception, test FPE_FLTINV */ + stage = 3; + got_exception = 0; + run_exception_test(simd_fault_handler, &stage, simd_exception_test2, + sizeof(simd_exception_test2), 0); + ok(got_exception == 1, "got exception: %i, should be 1\n", got_exception); } struct fpu_exception_info @@ -1325,6 +1377,8 @@ #elif defined(__x86_64__) +#define is_wow64 0 + #define UNW_FLAG_NHANDLER 0 #define UNW_FLAG_EHANDLER 1 #define UNW_FLAG_UHANDLER 2 @@ -1717,6 +1771,50 @@ #endif /* __x86_64__ */ #if defined(__i386__) || defined(__x86_64__) + +static void test_debug_registers(void) +{ + static const struct + { + ULONG_PTR dr0, dr1, dr2, dr3, dr6, dr7; + } + tests[] = + { + { 0x42424240, 0, 0x126bb070, 0x0badbad0, 0, 0xffff0115 }, + { 0x42424242, 0, 0x100f0fe7, 0x0abebabe, 0, 0x115 }, + }; + NTSTATUS status; + CONTEXT ctx; + int i; + + for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++) + { + memset(&ctx, 0, sizeof(ctx)); + ctx.ContextFlags = CONTEXT_DEBUG_REGISTERS; + ctx.Dr0 = tests[i].dr0; + ctx.Dr1 = tests[i].dr1; + ctx.Dr2 = tests[i].dr2; + ctx.Dr3 = tests[i].dr3; + ctx.Dr6 = tests[i].dr6; + ctx.Dr7 = tests[i].dr7; + + status = pNtSetContextThread(GetCurrentThread(), &ctx); + ok(status == STATUS_SUCCESS, "NtGetContextThread failed with %08x\n", status); + + memset(&ctx, 0, sizeof(ctx)); + ctx.ContextFlags = CONTEXT_DEBUG_REGISTERS; + + status = pNtGetContextThread(GetCurrentThread(), &ctx); + ok(status == STATUS_SUCCESS, "NtGetContextThread failed with %08x\n", status); + ok(ctx.Dr0 == tests[i].dr0, "test %d: expected %lx, got %lx\n", i, tests[i].dr0, (DWORD_PTR)ctx.Dr0); + ok(ctx.Dr1 == tests[i].dr1, "test %d: expected %lx, got %lx\n", i, tests[i].dr1, (DWORD_PTR)ctx.Dr1); + ok(ctx.Dr2 == tests[i].dr2, "test %d: expected %lx, got %lx\n", i, tests[i].dr2, (DWORD_PTR)ctx.Dr2); + ok(ctx.Dr3 == tests[i].dr3, "test %d: expected %lx, got %lx\n", i, tests[i].dr3, (DWORD_PTR)ctx.Dr3); + ok((ctx.Dr6 & 0xf00f) == tests[i].dr6, "test %d: expected %lx, got %lx\n", i, tests[i].dr6, (DWORD_PTR)ctx.Dr6); + ok((ctx.Dr7 & ~0xdc00) == tests[i].dr7, "test %d: expected %lx, got %lx\n", i, tests[i].dr7, (DWORD_PTR)ctx.Dr7); + } +} + static DWORD outputdebugstring_exceptions; static LONG CALLBACK outputdebugstring_vectored_handler(EXCEPTION_POINTERS *ExceptionInfo) @@ -1750,6 +1848,7 @@ outputdebugstring_exceptions = 0; OutputDebugStringA("Hello World"); + ok(outputdebugstring_exceptions == numexc, "OutputDebugStringA generated %d exceptions, expected %d\n", outputdebugstring_exceptions, numexc); @@ -1805,6 +1904,236 @@ pRtlRemoveVectoredExceptionHandler(vectored_handler); } +static DWORD debug_service_exceptions; + +static LONG CALLBACK debug_service_handler(EXCEPTION_POINTERS *ExceptionInfo) +{ + EXCEPTION_RECORD *rec = ExceptionInfo->ExceptionRecord; + trace("vect. handler %08x addr:%p\n", rec->ExceptionCode, rec->ExceptionAddress); + + ok(rec->ExceptionCode == EXCEPTION_BREAKPOINT, "ExceptionCode is %08x instead of %08x\n", + rec->ExceptionCode, EXCEPTION_BREAKPOINT); + +#ifdef __i386__ + ok(ExceptionInfo->ContextRecord->Eip == (DWORD)code_mem + 0x1c, + "expected Eip = %x, got %x\n", (DWORD)code_mem + 0x1c, ExceptionInfo->ContextRecord->Eip); + ok(rec->NumberParameters == (is_wow64 ? 1 : 3), + "ExceptionParameters is %d instead of %d\n", rec->NumberParameters, is_wow64 ? 1 : 3); + ok(rec->ExceptionInformation[0] == ExceptionInfo->ContextRecord->Eax, + "expected ExceptionInformation[0] = %x, got %lx\n", + ExceptionInfo->ContextRecord->Eax, rec->ExceptionInformation[0]); + if (!is_wow64) + { + ok(rec->ExceptionInformation[1] == 0x11111111, + "got ExceptionInformation[1] = %lx\n", rec->ExceptionInformation[1]); + ok(rec->ExceptionInformation[2] == 0x22222222, + "got ExceptionInformation[2] = %lx\n", rec->ExceptionInformation[2]); + } +#else + ok(ExceptionInfo->ContextRecord->Rip == (DWORD_PTR)code_mem + 0x2f, + "expected Rip = %lx, got %lx\n", (DWORD_PTR)code_mem + 0x2f, ExceptionInfo->ContextRecord->Rip); + ok(rec->NumberParameters == 1, + "ExceptionParameters is %d instead of 1\n", rec->NumberParameters); + ok(rec->ExceptionInformation[0] == ExceptionInfo->ContextRecord->Rax, + "expected ExceptionInformation[0] = %lx, got %lx\n", + ExceptionInfo->ContextRecord->Rax, rec->ExceptionInformation[0]); +#endif + + debug_service_exceptions++; + return (rec->ExceptionCode == EXCEPTION_BREAKPOINT) ? EXCEPTION_CONTINUE_EXECUTION : EXCEPTION_CONTINUE_SEARCH; +} + +#ifdef __i386__ + +static const BYTE call_debug_service_code[] = { + 0x53, /* pushl %ebx */ + 0x57, /* pushl %edi */ + 0x8b, 0x44, 0x24, 0x0c, /* movl 12(%esp),%eax */ + 0xb9, 0x11, 0x11, 0x11, 0x11, /* movl $0x11111111,%ecx */ + 0xba, 0x22, 0x22, 0x22, 0x22, /* movl $0x22222222,%edx */ + 0xbb, 0x33, 0x33, 0x33, 0x33, /* movl $0x33333333,%ebx */ + 0xbf, 0x44, 0x44, 0x44, 0x44, /* movl $0x44444444,%edi */ + 0xcd, 0x2d, /* int $0x2d */ + 0xeb, /* jmp $+17 */ + 0x0f, 0x1f, 0x00, /* nop */ + 0x31, 0xc0, /* xorl %eax,%eax */ + 0xeb, 0x0c, /* jmp $+14 */ + 0x90, 0x90, 0x90, 0x90, /* nop */ + 0x90, 0x90, 0x90, 0x90, + 0x90, + 0x31, 0xc0, /* xorl %eax,%eax */ + 0x40, /* incl %eax */ + 0x5f, /* popl %edi */ + 0x5b, /* popl %ebx */ + 0xc3, /* ret */ +}; + +#else + +static const BYTE call_debug_service_code[] = { + 0x53, /* push %rbx */ + 0x57, /* push %rdi */ + 0x48, 0x89, 0xc8, /* movl %rcx,%rax */ + 0x48, 0xb9, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, /* movabs $0x1111111111111111,%rcx */ + 0x48, 0xba, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, /* movabs $0x2222222222222222,%rdx */ + 0x48, 0xbb, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, /* movabs $0x3333333333333333,%rbx */ + 0x48, 0xbf, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, /* movabs $0x4444444444444444,%rdi */ + 0xcd, 0x2d, /* int $0x2d */ + 0xeb, /* jmp $+17 */ + 0x0f, 0x1f, 0x00, /* nop */ + 0x48, 0x31, 0xc0, /* xor %rax,%rax */ + 0xeb, 0x0e, /* jmp $+16 */ + 0x90, 0x90, 0x90, 0x90, /* nop */ + 0x90, 0x90, 0x90, 0x90, + 0x48, 0x31, 0xc0, /* xor %rax,%rax */ + 0x48, 0xff, 0xc0, /* inc %rax */ + 0x5f, /* pop %rdi */ + 0x5b, /* pop %rbx */ + 0xc3, /* ret */ +}; + +#endif + +static void test_debug_service(DWORD numexc) +{ + DWORD (CDECL *func)(DWORD_PTR) = code_mem; + DWORD expected_exc, expected_ret; + void *vectored_handler; + DWORD ret; + + /* code will return 0 if execution resumes immediately after "int $0x2d", otherwise 1 */ + memcpy(code_mem, call_debug_service_code, sizeof(call_debug_service_code)); + + vectored_handler = pRtlAddVectoredExceptionHandler(TRUE, &debug_service_handler); + ok(vectored_handler != 0, "RtlAddVectoredExceptionHandler failed\n"); + + expected_exc = numexc; + expected_ret = (numexc != 0); + + /* BREAKPOINT_BREAK */ + debug_service_exceptions = 0; + ret = func(0); + ok(debug_service_exceptions == expected_exc, + "BREAKPOINT_BREAK generated %u exceptions, expected %u\n", + debug_service_exceptions, expected_exc); + ok(ret == expected_ret, + "BREAKPOINT_BREAK returned %u, expected %u\n", ret, expected_ret); + + /* BREAKPOINT_PROMPT */ + debug_service_exceptions = 0; + ret = func(2); + ok(debug_service_exceptions == expected_exc, + "BREAKPOINT_PROMPT generated %u exceptions, expected %u\n", + debug_service_exceptions, expected_exc); + ok(ret == expected_ret, + "BREAKPOINT_PROMPT returned %u, expected %u\n", ret, expected_ret); + + /* invalid debug service */ + debug_service_exceptions = 0; + ret = func(6); + ok(debug_service_exceptions == expected_exc, + "invalid debug service generated %u exceptions, expected %u\n", + debug_service_exceptions, expected_exc); + ok(ret == expected_ret, + "invalid debug service returned %u, expected %u\n", ret, expected_ret); + + expected_exc = (is_wow64 ? numexc : 0); + expected_ret = (is_wow64 && numexc); + + /* BREAKPOINT_PRINT */ + debug_service_exceptions = 0; + ret = func(1); + ok(debug_service_exceptions == expected_exc, + "BREAKPOINT_PRINT generated %u exceptions, expected %u\n", + debug_service_exceptions, expected_exc); + ok(ret == expected_ret, + "BREAKPOINT_PRINT returned %u, expected %u\n", ret, expected_ret); + + /* BREAKPOINT_LOAD_SYMBOLS */ + debug_service_exceptions = 0; + ret = func(3); + ok(debug_service_exceptions == expected_exc, + "BREAKPOINT_LOAD_SYMBOLS generated %u exceptions, expected %u\n", + debug_service_exceptions, expected_exc); + ok(ret == expected_ret, + "BREAKPOINT_LOAD_SYMBOLS returned %u, expected %u\n", ret, expected_ret); + + /* BREAKPOINT_UNLOAD_SYMBOLS */ + debug_service_exceptions = 0; + ret = func(4); + ok(debug_service_exceptions == expected_exc, + "BREAKPOINT_UNLOAD_SYMBOLS generated %u exceptions, expected %u\n", + debug_service_exceptions, expected_exc); + ok(ret == expected_ret, + "BREAKPOINT_UNLOAD_SYMBOLS returned %u, expected %u\n", ret, expected_ret); + + /* BREAKPOINT_COMMAND_STRING */ + debug_service_exceptions = 0; + ret = func(5); + ok(debug_service_exceptions == expected_exc || broken(debug_service_exceptions == numexc), + "BREAKPOINT_COMMAND_STRING generated %u exceptions, expected %u\n", + debug_service_exceptions, expected_exc); + ok(ret == expected_ret || broken(ret == (numexc != 0)), + "BREAKPOINT_COMMAND_STRING returned %u, expected %u\n", ret, expected_ret); + + pRtlRemoveVectoredExceptionHandler(vectored_handler); +} + +static DWORD breakpoint_exceptions; + +static LONG CALLBACK breakpoint_handler(EXCEPTION_POINTERS *ExceptionInfo) +{ + EXCEPTION_RECORD *rec = ExceptionInfo->ExceptionRecord; + trace("vect. handler %08x addr:%p\n", rec->ExceptionCode, rec->ExceptionAddress); + + ok(rec->ExceptionCode == EXCEPTION_BREAKPOINT, "ExceptionCode is %08x instead of %08x\n", + rec->ExceptionCode, EXCEPTION_BREAKPOINT); + +#ifdef __i386__ + ok(ExceptionInfo->ContextRecord->Eip == (DWORD)code_mem + 1, + "expected Eip = %x, got %x\n", (DWORD)code_mem + 1, ExceptionInfo->ContextRecord->Eip); + ok(rec->NumberParameters == (is_wow64 ? 1 : 3), + "ExceptionParameters is %d instead of %d\n", rec->NumberParameters, is_wow64 ? 1 : 3); + ok(rec->ExceptionInformation[0] == 0, + "got ExceptionInformation[0] = %lx\n", rec->ExceptionInformation[0]); + ExceptionInfo->ContextRecord->Eip = (DWORD)code_mem + 2; +#else + ok(ExceptionInfo->ContextRecord->Rip == (DWORD_PTR)code_mem + 1, + "expected Rip = %lx, got %lx\n", (DWORD_PTR)code_mem + 1, ExceptionInfo->ContextRecord->Rip); + ok(rec->NumberParameters == 1, + "ExceptionParameters is %d instead of 1\n", rec->NumberParameters); + ok(rec->ExceptionInformation[0] == 0, + "got ExceptionInformation[0] = %lx\n", rec->ExceptionInformation[0]); + ExceptionInfo->ContextRecord->Rip = (DWORD_PTR)code_mem + 2; +#endif + + breakpoint_exceptions++; + return (rec->ExceptionCode == EXCEPTION_BREAKPOINT) ? EXCEPTION_CONTINUE_EXECUTION : EXCEPTION_CONTINUE_SEARCH; +} + +static const BYTE breakpoint_code[] = { + 0xcd, 0x03, /* int $0x3 */ + 0xc3, /* ret */ +}; + +static void test_breakpoint(DWORD numexc) +{ + DWORD (CDECL *func)(void) = code_mem; + void *vectored_handler; + + memcpy(code_mem, breakpoint_code, sizeof(breakpoint_code)); + + vectored_handler = pRtlAddVectoredExceptionHandler(TRUE, &breakpoint_handler); + ok(vectored_handler != 0, "RtlAddVectoredExceptionHandler failed\n"); + + breakpoint_exceptions = 0; + func(); + ok(breakpoint_exceptions == numexc, "int $0x3 generated %u exceptions, expected %u\n", + breakpoint_exceptions, numexc); + + pRtlRemoveVectoredExceptionHandler(vectored_handler); +} + static DWORD invalid_handle_exceptions; static LONG CALLBACK invalid_handle_vectored_handler(EXCEPTION_POINTERS *ExceptionInfo) @@ -1973,8 +2302,16 @@ test_stage = 6; test_ripevent(1); test_stage = 7; + test_debug_service(0); + test_stage = 8; + test_debug_service(1); + test_stage = 9; + test_breakpoint(0); + test_stage = 10; + test_breakpoint(1); + test_stage = 11; test_closehandle(0); - test_stage = 8; + test_stage = 12; test_closehandle(1); } else @@ -1987,8 +2324,11 @@ test_unwind(); test_exceptions(); test_rtlraiseexception(); + test_debug_registers(); test_outputdebugstring(1); test_ripevent(1); + test_debug_service(1); + test_breakpoint(1); test_closehandle(0); test_vectored_continue_handler(); test_debugger(); @@ -2007,8 +2347,11 @@ pRtlLookupFunctionEntry = (void *)GetProcAddress( hntdll, "RtlLookupFunctionEntry" ); + test_debug_registers(); test_outputdebugstring(1); test_ripevent(1); + test_debug_service(1); + test_breakpoint(1); test_closehandle(0); test_vectored_continue_handler(); test_virtual_unwind(); @@ -2020,5 +2363,5 @@ #endif - VirtualFree(code_mem, 0, MEM_FREE); + VirtualFree(code_mem, 0, MEM_RELEASE); } Index: modules/rostests/winetests/ntdll/file.c =================================================================== --- modules/rostests/winetests/ntdll/file.c (revision 70979) +++ modules/rostests/winetests/ntdll/file.c (working copy) @@ -704,7 +704,7 @@ apc_count = 0; U(iosb).Status = 0xdeadbabe; iosb.Information = 0xdeadbeef; - ok( !is_signaled( read ), "read handle is not signaled\n" ); + ok( !is_signaled( read ), "read handle is signaled\n" ); status = pNtReadFile( read, 0, apc, &apc_count, &iosb, buffer, 1, NULL, NULL ); ok( status == STATUS_PENDING, "wrong status %x\n", status ); ok( !is_signaled( read ), "read handle is signaled\n" ); @@ -717,7 +717,7 @@ Sleep(1); /* FIXME: needed for wine to run the i/o apc */ ok( U(iosb).Status == 0, "wrong status %x\n", U(iosb).Status ); ok( iosb.Information == 1, "wrong info %lu\n", iosb.Information ); - ok( is_signaled( read ), "read handle is signaled\n" ); + ok( is_signaled( read ), "read handle is not signaled\n" ); ok( !apc_count, "apc was called\n" ); apc_count = 0; SleepEx( 1, FALSE ); /* non-alertable sleep */ @@ -758,7 +758,7 @@ ok(ret && written == 1, "WriteFile error %d\n", GetLastError()); /* partial read is good enough */ Sleep(1); /* FIXME: needed for wine to run the i/o apc */ - ok( is_signaled( event ), "event is signaled\n" ); + ok( is_signaled( event ), "event is not signaled\n" ); ok( U(iosb).Status == 0, "wrong status %x\n", U(iosb).Status ); ok( iosb.Information == 1, "wrong info %lu\n", iosb.Information ); ok( !apc_count, "apc was called\n" ); @@ -789,7 +789,7 @@ ok( status == STATUS_INVALID_HANDLE, "wrong status %x\n", status ); ok( U(iosb).Status == 0xdeadbabe, "wrong status %x\n", U(iosb).Status ); ok( iosb.Information == 0xdeadbeef, "wrong info %lu\n", iosb.Information ); - ok( is_signaled( event ), "event is signaled\n" ); /* not reset on invalid handle */ + ok( is_signaled( event ), "event is not signaled\n" ); /* not reset on invalid handle */ ok( !apc_count, "apc was called\n" ); SleepEx( 1, TRUE ); /* alertable sleep */ ok( !apc_count, "apc was called\n" ); @@ -809,7 +809,7 @@ Sleep(1); /* FIXME: needed for wine to run the i/o apc */ ok( U(iosb).Status == STATUS_PIPE_BROKEN, "wrong status %x\n", U(iosb).Status ); ok( iosb.Information == 0, "wrong info %lu\n", iosb.Information ); - ok( is_signaled( event ), "event is signaled\n" ); + ok( is_signaled( event ), "event is not signaled\n" ); ok( !apc_count, "apc was called\n" ); SleepEx( 1, TRUE ); /* alertable sleep */ ok( apc_count == 1, "apc was not called\n" ); @@ -834,7 +834,7 @@ Sleep(1); /* FIXME: needed for wine to run the i/o apc */ ok( U(iosb).Status == STATUS_CANCELLED, "wrong status %x\n", U(iosb).Status ); ok( iosb.Information == 0, "wrong info %lu\n", iosb.Information ); - ok( is_signaled( event ), "event is signaled\n" ); + ok( is_signaled( event ), "event is not signaled\n" ); ok( !apc_count, "apc was called\n" ); SleepEx( 1, TRUE ); /* alertable sleep */ ok( apc_count == 1, "apc was not called\n" ); @@ -860,7 +860,7 @@ Sleep(1); /* FIXME: needed for wine to run the i/o apc */ ok( U(iosb).Status == STATUS_CANCELLED, "wrong status %x\n", U(iosb).Status ); ok( iosb.Information == 0, "wrong info %lu\n", iosb.Information ); - ok( is_signaled( event ), "event is signaled\n" ); + ok( is_signaled( event ), "event is not signaled\n" ); ok( !apc_count, "apc was called\n" ); SleepEx( 1, TRUE ); /* alertable sleep */ ok( apc_count == 1, "apc was not called\n" ); @@ -886,7 +886,7 @@ Sleep(1); /* FIXME: needed for wine to run the i/o apc */ ok( U(iosb).Status == STATUS_CANCELLED, "wrong status %x\n", U(iosb).Status ); ok( iosb.Information == 0, "wrong info %lu\n", iosb.Information ); - ok( is_signaled( event ), "event is signaled\n" ); + ok( is_signaled( event ), "event is not signaled\n" ); ok( !apc_count, "apc was called\n" ); SleepEx( 1, TRUE ); /* alertable sleep */ ok( apc_count == 1, "apc was not called\n" ); @@ -912,7 +912,7 @@ Sleep(1); /* FIXME: needed for wine to run the i/o apc */ ok( U(iosb).Status == STATUS_CANCELLED, "wrong status %x\n", U(iosb).Status ); ok( iosb.Information == 0, "wrong info %lu\n", iosb.Information ); - ok( is_signaled( event ), "event is signaled\n" ); + ok( is_signaled( event ), "event is not signaled\n" ); ok( !apc_count, "apc was called\n" ); SleepEx( 1, TRUE ); /* alertable sleep */ ok( apc_count == 2, "apc was not called\n" ); @@ -933,7 +933,7 @@ if (status == STATUS_PENDING) WaitForSingleObject( event, 1000 ); ok( U(iosb).Status == STATUS_SUCCESS, "wrong status %x\n", U(iosb).Status ); ok( iosb.Information == strlen(text), "wrong info %lu\n", iosb.Information ); - ok( is_signaled( event ), "event is signaled\n" ); + ok( is_signaled( event ), "event is not signaled\n" ); ok( !apc_count, "apc was called\n" ); SleepEx( 1, TRUE ); /* alertable sleep */ ok( apc_count == 1, "apc was not called\n" ); @@ -950,7 +950,7 @@ if (status == STATUS_PENDING) WaitForSingleObject( event, 1000 ); ok( U(iosb).Status == STATUS_SUCCESS, "wrong status %x\n", U(iosb).Status ); ok( iosb.Information == strlen(text), "wrong info %lu\n", iosb.Information ); - ok( is_signaled( event ), "event is signaled\n" ); + ok( is_signaled( event ), "event is not signaled\n" ); ok( !apc_count, "apc was called\n" ); SleepEx( 1, TRUE ); /* alertable sleep */ ok( apc_count == 1, "apc was not called\n" ); @@ -967,7 +967,7 @@ WaitForSingleObject( event, 1000 ); ok( U(iosb).Status == STATUS_END_OF_FILE, "wrong status %x\n", U(iosb).Status ); ok( iosb.Information == 0, "wrong info %lu\n", iosb.Information ); - ok( is_signaled( event ), "event is signaled\n" ); + ok( is_signaled( event ), "event is not signaled\n" ); ok( !apc_count, "apc was called\n" ); SleepEx( 1, TRUE ); /* alertable sleep */ ok( apc_count == 1, "apc was not called\n" ); @@ -988,7 +988,7 @@ if (status == STATUS_PENDING) WaitForSingleObject( event, 1000 ); ok( U(iosb).Status == STATUS_SUCCESS, "wrong status %x\n", U(iosb).Status ); ok( iosb.Information == strlen(text), "wrong info %lu\n", iosb.Information ); - ok( is_signaled( event ), "event is signaled\n" ); + ok( is_signaled( event ), "event is not signaled\n" ); ok( !apc_count, "apc was called\n" ); SleepEx( 1, TRUE ); /* alertable sleep */ ok( apc_count == 1, "apc was not called\n" ); @@ -1002,7 +1002,7 @@ ok( status == STATUS_SUCCESS, "wrong status %x\n", status ); ok( U(iosb).Status == STATUS_SUCCESS, "wrong status %x\n", U(iosb).Status ); ok( iosb.Information == strlen(text), "wrong info %lu\n", iosb.Information ); - ok( is_signaled( event ), "event is signaled\n" ); + ok( is_signaled( event ), "event is not signaled\n" ); ok( !apc_count, "apc was called\n" ); SleepEx( 1, TRUE ); /* alertable sleep */ todo_wine ok( !apc_count, "apc was called\n" ); @@ -1166,39 +1166,6 @@ if ( rc == STATUS_SUCCESS ) pNtClose(hslot); /* - * Test that the length field is checked properly - */ - attr.Length = 0; - rc = pNtCreateMailslotFile(&hslot, DesiredAccess, - &attr, &IoStatusBlock, CreateOptions, MailslotQuota, MaxMessageSize, - &TimeOut); - todo_wine ok( rc == STATUS_INVALID_PARAMETER, "rc = %x not c000000d STATUS_INVALID_PARAMETER\n", rc); - - if (rc == STATUS_SUCCESS) pNtClose(hslot); - - attr.Length = sizeof(OBJECT_ATTRIBUTES)+1; - rc = pNtCreateMailslotFile(&hslot, DesiredAccess, - &attr, &IoStatusBlock, CreateOptions, MailslotQuota, MaxMessageSize, - &TimeOut); - todo_wine ok( rc == STATUS_INVALID_PARAMETER, "rc = %x not c000000d STATUS_INVALID_PARAMETER\n", rc); - - if (rc == STATUS_SUCCESS) pNtClose(hslot); - - /* - * Test handling of a NULL unicode string in ObjectName - */ - InitializeObjectAttributes(&attr, &str, OBJ_CASE_INSENSITIVE, 0, NULL); - attr.ObjectName = NULL; - rc = pNtCreateMailslotFile(&hslot, DesiredAccess, - &attr, &IoStatusBlock, CreateOptions, MailslotQuota, MaxMessageSize, - &TimeOut); - ok( rc == STATUS_OBJECT_PATH_SYNTAX_BAD || - rc == STATUS_INVALID_PARAMETER, - "rc = %x not STATUS_OBJECT_PATH_SYNTAX_BAD or STATUS_INVALID_PARAMETER\n", rc); - - if (rc == STATUS_SUCCESS) pNtClose(hslot); - - /* * Test a valid call */ InitializeObjectAttributes(&attr, &str, OBJ_CASE_INSENSITIVE, 0, NULL); Index: modules/rostests/winetests/ntdll/info.c =================================================================== --- modules/rostests/winetests/ntdll/info.c (revision 70979) +++ modules/rostests/winetests/ntdll/info.c (working copy) @@ -23,6 +23,7 @@ #include static NTSTATUS (WINAPI * pNtQuerySystemInformation)(SYSTEM_INFORMATION_CLASS, PVOID, ULONG, PULONG); +static NTSTATUS (WINAPI * pNtQuerySystemInformationEx)(SYSTEM_INFORMATION_CLASS, void*, ULONG, void*, ULONG, ULONG*); static NTSTATUS (WINAPI * pNtPowerInformation)(POWER_INFORMATION_LEVEL, PVOID, ULONG, PVOID, ULONG); static NTSTATUS (WINAPI * pNtQueryInformationProcess)(HANDLE, PROCESSINFOCLASS, PVOID, ULONG, PULONG); static NTSTATUS (WINAPI * pNtQueryInformationThread)(HANDLE, THREADINFOCLASS, PVOID, ULONG, PULONG); @@ -36,6 +37,7 @@ static NTSTATUS (WINAPI * pNtClose)(HANDLE); static ULONG (WINAPI * pNtGetCurrentProcessorNumber)(void); static BOOL (WINAPI * pIsWow64Process)(HANDLE, PBOOL); +static BOOL (WINAPI * pGetLogicalProcessorInformationEx)(LOGICAL_PROCESSOR_RELATIONSHIP,SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX*,DWORD*); static BOOL is_wow64; @@ -56,6 +58,8 @@ { /* All needed functions are NT based, so using GetModuleHandle is a good check */ HMODULE hntdll = GetModuleHandleA("ntdll"); + HMODULE hkernel32 = GetModuleHandleA("kernel32"); + if (!hntdll) { win_skip("Not running on NT\n"); @@ -78,8 +82,16 @@ /* not present before XP */ pNtGetCurrentProcessorNumber = (void *) GetProcAddress(hntdll, "NtGetCurrentProcessorNumber"); - pIsWow64Process = (void *)GetProcAddress(GetModuleHandleA("kernel32.dll"), "IsWow64Process"); + pIsWow64Process = (void *)GetProcAddress(hkernel32, "IsWow64Process"); if (!pIsWow64Process || !pIsWow64Process( GetCurrentProcess(), &is_wow64 )) is_wow64 = FALSE; + + /* starting with Win7 */ + pNtQuerySystemInformationEx = (void *) GetProcAddress(hntdll, "NtQuerySystemInformationEx"); + if (!pNtQuerySystemInformationEx) + win_skip("NtQuerySystemInformationEx() is not supported, some tests will be skipped.\n"); + + pGetLogicalProcessorInformationEx = (void *) GetProcAddress(hkernel32, "GetLogicalProcessorInformationEx"); + return TRUE; } @@ -288,7 +300,7 @@ /* test ReturnLength */ ReturnLength = 0; status = pNtQuerySystemInformation(SystemProcessInformation, NULL, 0, &ReturnLength); - ok( status == STATUS_INFO_LENGTH_MISMATCH, "Expected STATUS_LENGTH_MISMATCH got %08x\n", status); + ok( status == STATUS_INFO_LENGTH_MISMATCH, "Expected STATUS_INFO_LENGTH_MISMATCH got %08x\n", status); ok( ReturnLength > 0 || broken(ReturnLength == 0) /* NT4, Win2K */, "Expected a ReturnLength to show the needed length\n"); @@ -474,13 +486,15 @@ static void test_query_handle(void) { NTSTATUS status; - ULONG ReturnLength; + ULONG ExpectedLength, ReturnLength; ULONG SystemInformationLength = sizeof(SYSTEM_HANDLE_INFORMATION); SYSTEM_HANDLE_INFORMATION* shi = HeapAlloc(GetProcessHeap(), 0, SystemInformationLength); - HANDLE event_handle; + HANDLE EventHandle; + BOOL found; + INT i; - event_handle = CreateEventA(NULL, FALSE, FALSE, NULL); - ok( event_handle != NULL, "CreateEventA failed %u\n", GetLastError() ); + EventHandle = CreateEventA(NULL, FALSE, FALSE, NULL); + ok( EventHandle != NULL, "CreateEventA failed %u\n", GetLastError() ); /* Request the needed length : a SystemInformationLength greater than one struct sets ReturnLength */ ReturnLength = 0xdeadbeef; @@ -493,31 +507,41 @@ ReturnLength = 0xdeadbeef; status = pNtQuerySystemInformation(SystemHandleInformation, shi, SystemInformationLength, &ReturnLength); - if (status != STATUS_INFO_LENGTH_MISMATCH) /* vista */ + while (status == STATUS_INFO_LENGTH_MISMATCH) /* Vista / 2008 */ { - ULONG ExpectedLength = FIELD_OFFSET(SYSTEM_HANDLE_INFORMATION, Handle[shi->Count]); - unsigned int i; - BOOL found = FALSE; + SystemInformationLength *= 2; + shi = HeapReAlloc(GetProcessHeap(), 0, shi, SystemInformationLength); + status = pNtQuerySystemInformation(SystemHandleInformation, shi, SystemInformationLength, &ReturnLength); + } + ok( status == STATUS_SUCCESS, "Expected STATUS_SUCCESS, got %08x\n", status ); + ExpectedLength = FIELD_OFFSET(SYSTEM_HANDLE_INFORMATION, Handle[shi->Count]); + ok( ReturnLength == ExpectedLength || broken(ReturnLength == ExpectedLength - sizeof(DWORD)), /* Vista / 2008 */ + "Expected length %u, got %u\n", ExpectedLength, ReturnLength ); + ok( shi->Count > 1, "Expected more than 1 handle, got %u\n", shi->Count ); + for (i = 0, found = FALSE; i < shi->Count && !found; i++) + found = (shi->Handle[i].OwnerPid == GetCurrentProcessId()) && + ((HANDLE)(ULONG_PTR)shi->Handle[i].HandleValue == EventHandle); + ok( found, "Expected to find event handle in handle list\n" ); - ok( status == STATUS_SUCCESS, "Expected STATUS_SUCCESS, got %08x\n", status ); - ok( ReturnLength == ExpectedLength, "Expected length %u, got %u\n", ExpectedLength, ReturnLength ); - ok( shi->Count > 1, "Expected more than 1 handles, got %u\n", shi->Count ); - for (i = 0; i < shi->Count; i++) - { - if (shi->Handle[i].OwnerPid == GetCurrentProcessId() && - (HANDLE)(ULONG_PTR)shi->Handle[i].HandleValue == event_handle) - { - found = TRUE; - break; - } - } - ok( found, "Expected to find event handle in handle list\n" ); + CloseHandle(EventHandle); + + ReturnLength = 0xdeadbeef; + status = pNtQuerySystemInformation(SystemHandleInformation, shi, SystemInformationLength, &ReturnLength); + while (status == STATUS_INFO_LENGTH_MISMATCH) /* Vista / 2008 */ + { + SystemInformationLength *= 2; + shi = HeapReAlloc(GetProcessHeap(), 0, shi, SystemInformationLength); + status = pNtQuerySystemInformation(SystemHandleInformation, shi, SystemInformationLength, &ReturnLength); } + ok( status == STATUS_SUCCESS, "Expected STATUS_SUCCESS, got %08x\n", status ); + for (i = 0, found = FALSE; i < shi->Count && !found; i++) + found = (shi->Handle[i].OwnerPid == GetCurrentProcessId()) && + ((HANDLE)(ULONG_PTR)shi->Handle[i].HandleValue == EventHandle); + ok( !found, "Unexpectedly found event handle in handle list\n" ); status = pNtQuerySystemInformation(SystemHandleInformation, NULL, SystemInformationLength, &ReturnLength); ok( status == STATUS_ACCESS_VIOLATION, "Expected STATUS_ACCESS_VIOLATION, got %08x\n", status ); - CloseHandle(event_handle); HeapFree( GetProcessHeap(), 0, shi); } @@ -684,6 +708,110 @@ HeapFree(GetProcessHeap(), 0, slpi); } +static void test_query_logicalprocex(void) +{ + SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX *infoex, *infoex2; + DWORD relationship, len2, len; + NTSTATUS status; + BOOL ret; + + if (!pNtQuerySystemInformationEx) + return; + + len = 0; + relationship = RelationProcessorCore; + status = pNtQuerySystemInformationEx(SystemLogicalProcessorInformationEx, &relationship, sizeof(relationship), NULL, 0, &len); + ok(status == STATUS_INFO_LENGTH_MISMATCH, "got 0x%08x\n", status); + ok(len > 0, "got %u\n", len); + + len = 0; + relationship = RelationAll; + status = pNtQuerySystemInformationEx(SystemLogicalProcessorInformationEx, &relationship, sizeof(relationship), NULL, 0, &len); + ok(status == STATUS_INFO_LENGTH_MISMATCH, "got 0x%08x\n", status); + ok(len > 0, "got %u\n", len); + + len2 = 0; + ret = pGetLogicalProcessorInformationEx(RelationAll, NULL, &len2); + ok(!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER, "got %d, error %d\n", ret, GetLastError()); + ok(len == len2, "got %u, expected %u\n", len2, len); + + if (len && len == len2) { + int j, i; + + infoex = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, len); + infoex2 = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, len); + + status = pNtQuerySystemInformationEx(SystemLogicalProcessorInformationEx, &relationship, sizeof(relationship), infoex, len, &len); + ok(status == STATUS_SUCCESS, "got 0x%08x\n", status); + + ret = pGetLogicalProcessorInformationEx(RelationAll, infoex2, &len2); + ok(ret, "got %d, error %d\n", ret, GetLastError()); + ok(!memcmp(infoex, infoex2, len), "returned info data mismatch\n"); + + for(i = 0; status == STATUS_SUCCESS && i < len; ){ + SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX *ex = (void*)(((char *)infoex) + i); + + ok(ex->Relationship >= RelationProcessorCore && ex->Relationship <= RelationGroup, + "Got invalid relationship value: 0x%x\n", ex->Relationship); + if (!ex->Size) + { + ok(0, "got infoex[%u].Size=0\n", i); + break; + } + + trace("infoex[%u].Size: %u\n", i, ex->Size); + switch(ex->Relationship){ + case RelationProcessorCore: + case RelationProcessorPackage: + trace("infoex[%u].Relationship: 0x%x (Core == 0x0 or Package == 0x3)\n", i, ex->Relationship); + trace("infoex[%u].Processor.Flags: 0x%x\n", i, ex->Processor.Flags); +#ifndef __REACTOS__ + trace("infoex[%u].Processor.EfficiencyClass: 0x%x\n", i, ex->Processor.EfficiencyClass); +#endif + trace("infoex[%u].Processor.GroupCount: 0x%x\n", i, ex->Processor.GroupCount); + for(j = 0; j < ex->Processor.GroupCount; ++j){ + trace("infoex[%u].Processor.GroupMask[%u].Mask: 0x%lx\n", i, j, ex->Processor.GroupMask[j].Mask); + trace("infoex[%u].Processor.GroupMask[%u].Group: 0x%x\n", i, j, ex->Processor.GroupMask[j].Group); + } + break; + case RelationNumaNode: + trace("infoex[%u].Relationship: 0x%x (NumaNode)\n", i, ex->Relationship); + trace("infoex[%u].NumaNode.NodeNumber: 0x%x\n", i, ex->NumaNode.NodeNumber); + trace("infoex[%u].NumaNode.GroupMask.Mask: 0x%lx\n", i, ex->NumaNode.GroupMask.Mask); + trace("infoex[%u].NumaNode.GroupMask.Group: 0x%x\n", i, ex->NumaNode.GroupMask.Group); + break; + case RelationCache: + trace("infoex[%u].Relationship: 0x%x (Cache)\n", i, ex->Relationship); + trace("infoex[%u].Cache.Level: 0x%x\n", i, ex->Cache.Level); + trace("infoex[%u].Cache.Associativity: 0x%x\n", i, ex->Cache.Associativity); + trace("infoex[%u].Cache.LineSize: 0x%x\n", i, ex->Cache.LineSize); + trace("infoex[%u].Cache.CacheSize: 0x%x\n", i, ex->Cache.CacheSize); + trace("infoex[%u].Cache.Type: 0x%x\n", i, ex->Cache.Type); + trace("infoex[%u].Cache.GroupMask.Mask: 0x%lx\n", i, ex->Cache.GroupMask.Mask); + trace("infoex[%u].Cache.GroupMask.Group: 0x%x\n", i, ex->Cache.GroupMask.Group); + break; + case RelationGroup: + trace("infoex[%u].Relationship: 0x%x (Group)\n", i, ex->Relationship); + trace("infoex[%u].Group.MaximumGroupCount: 0x%x\n", i, ex->Group.MaximumGroupCount); + trace("infoex[%u].Group.ActiveGroupCount: 0x%x\n", i, ex->Group.ActiveGroupCount); + for(j = 0; j < ex->Group.ActiveGroupCount; ++j){ + trace("infoex[%u].Group.GroupInfo[%u].MaximumProcessorCount: 0x%x\n", i, j, ex->Group.GroupInfo[j].MaximumProcessorCount); + trace("infoex[%u].Group.GroupInfo[%u].ActiveProcessorCount: 0x%x\n", i, j, ex->Group.GroupInfo[j].ActiveProcessorCount); + trace("infoex[%u].Group.GroupInfo[%u].ActiveProcessorMask: 0x%lx\n", i, j, ex->Group.GroupInfo[j].ActiveProcessorMask); + } + break; + default: + break; + } + + i += ex->Size; + } + + HeapFree(GetProcessHeap(), 0, infoex); + HeapFree(GetProcessHeap(), 0, infoex2); + } +} + static void test_query_processor_power_info(void) { NTSTATUS status; @@ -1070,7 +1198,7 @@ status = pNtQueryInformationProcess(NULL, ProcessDebugPort, &debug_port, sizeof(debug_port), NULL); - ok(status == STATUS_INVALID_HANDLE, "Expected STATUS_ACCESS_VIOLATION, got %#x.\n", status); + ok(status == STATUS_INVALID_HANDLE, "Expected STATUS_INVALID_HANDLE, got %#x.\n", status); status = pNtQueryInformationProcess(GetCurrentProcess(), ProcessDebugPort, &debug_port, sizeof(debug_port) - 1, NULL); @@ -1293,27 +1421,27 @@ static void test_query_process_debug_flags(int argc, char **argv) { + static const DWORD test_flags[] = { DEBUG_PROCESS, + DEBUG_ONLY_THIS_PROCESS, + DEBUG_PROCESS | DEBUG_ONLY_THIS_PROCESS, + CREATE_SUSPENDED }; DWORD debug_flags = 0xdeadbeef; char cmdline[MAX_PATH]; PROCESS_INFORMATION pi; STARTUPINFOA si = { 0 }; NTSTATUS status; + DEBUG_EVENT ev; + DWORD result; BOOL ret; + int i, j; - sprintf(cmdline, "%s %s %s", argv[0], argv[1], "debuggee"); + /* test invalid arguments */ + status = pNtQueryInformationProcess(NULL, ProcessDebugFlags, NULL, 0, NULL); + ok(status == STATUS_INFO_LENGTH_MISMATCH || broken(status == STATUS_INVALID_INFO_CLASS) /* WOW64 */, + "Expected STATUS_INFO_LENGTH_MISMATCH, got %#x.\n", status); - si.cb = sizeof(si); - ret = CreateProcessA(NULL, cmdline, NULL, NULL, FALSE, DEBUG_PROCESS | DEBUG_ONLY_THIS_PROCESS, NULL, NULL, &si, &pi); - ok(ret, "CreateProcess failed, last error %#x.\n", GetLastError()); - if (!ret) return; - - status = pNtQueryInformationProcess(NULL, ProcessDebugFlags, - NULL, 0, NULL); - ok(status == STATUS_INFO_LENGTH_MISMATCH || broken(status == STATUS_INVALID_INFO_CLASS) /* NT4 */, "Expected STATUS_INFO_LENGTH_MISMATCH, got %#x.\n", status); - - status = pNtQueryInformationProcess(NULL, ProcessDebugFlags, - NULL, sizeof(debug_flags), NULL); - ok(status == STATUS_INVALID_HANDLE || status == STATUS_ACCESS_VIOLATION || broken(status == STATUS_INVALID_INFO_CLASS) /* W7PROX64 (32-bit) */, + status = pNtQueryInformationProcess(NULL, ProcessDebugFlags, NULL, sizeof(debug_flags), NULL); + ok(status == STATUS_INVALID_HANDLE || status == STATUS_ACCESS_VIOLATION || broken(status == STATUS_INVALID_INFO_CLASS) /* WOW64 */, "Expected STATUS_INVALID_HANDLE, got %#x.\n", status); status = pNtQueryInformationProcess(GetCurrentProcess(), ProcessDebugFlags, @@ -1322,45 +1450,123 @@ status = pNtQueryInformationProcess(NULL, ProcessDebugFlags, &debug_flags, sizeof(debug_flags), NULL); - ok(status == STATUS_INVALID_HANDLE || broken(status == STATUS_INVALID_INFO_CLASS) /* NT4 */, "Expected STATUS_ACCESS_VIOLATION, got %#x.\n", status); + ok(status == STATUS_INVALID_HANDLE || broken(status == STATUS_INVALID_INFO_CLASS) /* WOW64 */, + "Expected STATUS_INVALID_HANDLE, got %#x.\n", status); status = pNtQueryInformationProcess(GetCurrentProcess(), ProcessDebugFlags, &debug_flags, sizeof(debug_flags) - 1, NULL); - ok(status == STATUS_INFO_LENGTH_MISMATCH || broken(status == STATUS_INVALID_INFO_CLASS) /* NT4 */, "Expected STATUS_INFO_LENGTH_MISMATCH, got %#x.\n", status); + ok(status == STATUS_INFO_LENGTH_MISMATCH, "Expected STATUS_INFO_LENGTH_MISMATCH, got %#x.\n", status); status = pNtQueryInformationProcess(GetCurrentProcess(), ProcessDebugFlags, &debug_flags, sizeof(debug_flags) + 1, NULL); - ok(status == STATUS_INFO_LENGTH_MISMATCH || broken(status == STATUS_INVALID_INFO_CLASS) /* NT4 */, "Expected STATUS_INFO_LENGTH_MISMATCH, got %#x.\n", status); + ok(status == STATUS_INFO_LENGTH_MISMATCH, "Expected STATUS_INFO_LENGTH_MISMATCH, got %#x.\n", status); + /* test ProcessDebugFlags of current process */ status = pNtQueryInformationProcess(GetCurrentProcess(), ProcessDebugFlags, &debug_flags, sizeof(debug_flags), NULL); - ok(!status || broken(status == STATUS_INVALID_INFO_CLASS) /* NT4 */, "NtQueryInformationProcess failed, status %#x.\n", status); - ok(debug_flags == TRUE|| broken(status == STATUS_INVALID_INFO_CLASS) /* NT4 */, "Expected flag TRUE, got %x.\n", debug_flags); + ok(!status, "NtQueryInformationProcess failed, status %#x.\n", status); + ok(debug_flags == TRUE, "Expected flag TRUE, got %x.\n", debug_flags); - status = pNtQueryInformationProcess(pi.hProcess, ProcessDebugFlags, - &debug_flags, sizeof(debug_flags), NULL); - ok(!status || broken(status == STATUS_INVALID_INFO_CLASS) /* NT4 */, "NtQueryInformationProcess failed, status %#x.\n", status); - ok(debug_flags == FALSE || broken(status == STATUS_INVALID_INFO_CLASS) /* NT4 */, "Expected flag FALSE, got %x.\n", debug_flags); - - for (;;) + for (i = 0; i < sizeof(test_flags)/sizeof(test_flags[0]); i++) { - DEBUG_EVENT ev; + DWORD expected_flags = !(test_flags[i] & DEBUG_ONLY_THIS_PROCESS); + sprintf(cmdline, "%s %s %s", argv[0], argv[1], "debuggee"); - ret = WaitForDebugEvent(&ev, INFINITE); - ok(ret, "WaitForDebugEvent failed, last error %#x.\n", GetLastError()); - if (!ret) break; + si.cb = sizeof(si); + ret = CreateProcessA(NULL, cmdline, NULL, NULL, FALSE, test_flags[i], NULL, NULL, &si, &pi); + ok(ret, "CreateProcess failed, last error %#x.\n", GetLastError()); - if (ev.dwDebugEventCode == EXIT_PROCESS_DEBUG_EVENT) break; + if (!(test_flags[i] & (DEBUG_PROCESS | DEBUG_ONLY_THIS_PROCESS))) + { + /* test ProcessDebugFlags before attaching with debugger */ + status = pNtQueryInformationProcess(pi.hProcess, ProcessDebugFlags, + &debug_flags, sizeof(debug_flags), NULL); + ok(!status, "NtQueryInformationProcess failed, status %#x.\n", status); + ok(debug_flags == TRUE, "Expected flag TRUE, got %x.\n", debug_flags); - ret = ContinueDebugEvent(ev.dwProcessId, ev.dwThreadId, DBG_CONTINUE); - ok(ret, "ContinueDebugEvent failed, last error %#x.\n", GetLastError()); - if (!ret) break; + ret = DebugActiveProcess(pi.dwProcessId); + ok(ret, "DebugActiveProcess failed, last error %#x.\n", GetLastError()); + expected_flags = FALSE; + } + + /* test ProcessDebugFlags after attaching with debugger */ + status = pNtQueryInformationProcess(pi.hProcess, ProcessDebugFlags, + &debug_flags, sizeof(debug_flags), NULL); + ok(!status, "NtQueryInformationProcess failed, status %#x.\n", status); + ok(debug_flags == expected_flags, "Expected flag %x, got %x.\n", expected_flags, debug_flags); + + if (!(test_flags[i] & CREATE_SUSPENDED)) + { + /* Continue a couple of times to make sure the process is fully initialized, + * otherwise Windows XP deadlocks in the following DebugActiveProcess(). */ + for (;;) + { + ret = WaitForDebugEvent(&ev, 1000); + ok(ret, "WaitForDebugEvent failed, last error %#x.\n", GetLastError()); + if (!ret) break; + + if (ev.dwDebugEventCode == LOAD_DLL_DEBUG_EVENT) break; + + ret = ContinueDebugEvent(ev.dwProcessId, ev.dwThreadId, DBG_CONTINUE); + ok(ret, "ContinueDebugEvent failed, last error %#x.\n", GetLastError()); + if (!ret) break; + } + + result = SuspendThread(pi.hThread); + ok(result == 0, "Expected 0, got %u.\n", result); + } + + ret = DebugActiveProcessStop(pi.dwProcessId); + ok(ret, "DebugActiveProcessStop failed, last error %#x.\n", GetLastError()); + + /* test ProcessDebugFlags after detaching debugger */ + status = pNtQueryInformationProcess(pi.hProcess, ProcessDebugFlags, + &debug_flags, sizeof(debug_flags), NULL); + ok(!status, "NtQueryInformationProcess failed, status %#x.\n", status); + ok(debug_flags == expected_flags, "Expected flag %x, got %x.\n", expected_flags, debug_flags); + + ret = DebugActiveProcess(pi.dwProcessId); + ok(ret, "DebugActiveProcess failed, last error %#x.\n", GetLastError()); + + /* test ProcessDebugFlags after re-attaching debugger */ + status = pNtQueryInformationProcess(pi.hProcess, ProcessDebugFlags, + &debug_flags, sizeof(debug_flags), NULL); + ok(!status, "NtQueryInformationProcess failed, status %#x.\n", status); + ok(debug_flags == FALSE, "Expected flag FALSE, got %x.\n", debug_flags); + + result = ResumeThread(pi.hThread); + todo_wine ok(result == 2, "Expected 2, got %u.\n", result); + + /* Wait until the process is terminated. On Windows XP the process randomly + * gets stuck in a non-continuable exception, so stop after 100 iterations. + * On Windows 2003, the debugged process disappears (or stops?) without + * any EXIT_PROCESS_DEBUG_EVENT after a couple of events. */ + for (j = 0; j < 100; j++) + { + ret = WaitForDebugEvent(&ev, 1000); + ok(ret || broken(GetLastError() == ERROR_SEM_TIMEOUT), + "WaitForDebugEvent failed, last error %#x.\n", GetLastError()); + if (!ret) break; + + if (ev.dwDebugEventCode == EXIT_PROCESS_DEBUG_EVENT) break; + + ret = ContinueDebugEvent(ev.dwProcessId, ev.dwThreadId, DBG_CONTINUE); + ok(ret, "ContinueDebugEvent failed, last error %#x.\n", GetLastError()); + if (!ret) break; + } + ok(j < 100 || broken(j >= 100) /* Win XP */, "Expected less than 100 debug events.\n"); + + /* test ProcessDebugFlags after process has terminated */ + status = pNtQueryInformationProcess(pi.hProcess, ProcessDebugFlags, + &debug_flags, sizeof(debug_flags), NULL); + ok(!status, "NtQueryInformationProcess failed, status %#x.\n", status); + ok(debug_flags == FALSE, "Expected flag FALSE, got %x.\n", debug_flags); + + ret = CloseHandle(pi.hThread); + ok(ret, "CloseHandle failed, last error %#x.\n", GetLastError()); + ret = CloseHandle(pi.hProcess); + ok(ret, "CloseHandle failed, last error %#x.\n", GetLastError()); } - - ret = CloseHandle(pi.hThread); - ok(ret, "CloseHandle failed, last error %#x.\n", GetLastError()); - ret = CloseHandle(pi.hProcess); - ok(ret, "CloseHandle failed, last error %#x.\n", GetLastError()); } static void test_readvirtualmemory(void) @@ -1780,6 +1986,19 @@ CloseHandle(thread); } +static void test_query_data_alignment(void) +{ + ULONG ReturnLength; + NTSTATUS status; + DWORD value; + + value = 0xdeadbeef; + status = pNtQuerySystemInformation(SystemRecommendedSharedDataAlignment, &value, sizeof(value), &ReturnLength); + ok(status == STATUS_SUCCESS, "Expected STATUS_SUCCESS, got %08x\n", status); + ok(sizeof(value) == ReturnLength, "Inconsistent length %u\n", ReturnLength); + ok(value == 64, "Expected 64, got %u\n", value); +} + START_TEST(info) { char **argv; @@ -1844,6 +2063,7 @@ /* 0x49 SystemLogicalProcessorInformation */ trace("Starting test_query_logicalproc()\n"); test_query_logicalproc(); + test_query_logicalprocex(); /* NtPowerInformation */ @@ -1911,4 +2131,7 @@ trace("Starting test_thread_start_address()\n"); test_thread_start_address(); + + trace("Starting test_query_data_alignment()\n"); + test_query_data_alignment(); } Index: modules/rostests/winetests/ntdll/ntdll_test.h =================================================================== --- modules/rostests/winetests/ntdll/ntdll_test.h (revision 70979) +++ modules/rostests/winetests/ntdll/ntdll_test.h (working copy) @@ -20,10 +20,6 @@ #include -#ifndef _WIN32_WINNT -#define _WIN32_WINNT 0x500 /* For NTSTATUS */ -#endif - #include "ntstatus.h" #define WIN32_NO_STATUS #include "windef.h" Index: modules/rostests/winetests/ntdll/om.c =================================================================== --- modules/rostests/winetests/ntdll/om.c (revision 70979) +++ modules/rostests/winetests/ntdll/om.c (working copy) @@ -33,12 +33,23 @@ static NTSTATUS (WINAPI *pNtOpenEvent) ( PHANDLE, ACCESS_MASK, const POBJECT_ATTRIBUTES); static NTSTATUS (WINAPI *pNtPulseEvent) ( HANDLE, PULONG ); static NTSTATUS (WINAPI *pNtQueryEvent) ( HANDLE, EVENT_INFORMATION_CLASS, PVOID, ULONG, PULONG ); +static NTSTATUS (WINAPI *pNtCreateJobObject)( PHANDLE, ACCESS_MASK, POBJECT_ATTRIBUTES ); +static NTSTATUS (WINAPI *pNtOpenJobObject)( PHANDLE, ACCESS_MASK, POBJECT_ATTRIBUTES ); +static NTSTATUS (WINAPI *pNtCreateKey)( PHANDLE, ACCESS_MASK, POBJECT_ATTRIBUTES, ULONG, + const UNICODE_STRING *, ULONG, PULONG ); +static NTSTATUS (WINAPI *pNtOpenKey)( PHANDLE, ACCESS_MASK, POBJECT_ATTRIBUTES ); +static NTSTATUS (WINAPI *pNtDeleteKey)( HANDLE ); +static NTSTATUS (WINAPI *pNtCreateMailslotFile)( PHANDLE, ACCESS_MASK, POBJECT_ATTRIBUTES, PIO_STATUS_BLOCK, + ULONG, ULONG, ULONG, PLARGE_INTEGER ); static NTSTATUS (WINAPI *pNtCreateMutant)( PHANDLE, ACCESS_MASK, const POBJECT_ATTRIBUTES, BOOLEAN ); static NTSTATUS (WINAPI *pNtOpenMutant) ( PHANDLE, ACCESS_MASK, const POBJECT_ATTRIBUTES ); static NTSTATUS (WINAPI *pNtCreateSemaphore)( PHANDLE, ACCESS_MASK,const POBJECT_ATTRIBUTES,LONG,LONG ); +static NTSTATUS (WINAPI *pNtOpenSemaphore)( PHANDLE, ACCESS_MASK, const POBJECT_ATTRIBUTES ); static NTSTATUS (WINAPI *pNtCreateTimer) ( PHANDLE, ACCESS_MASK, const POBJECT_ATTRIBUTES, TIMER_TYPE ); +static NTSTATUS (WINAPI *pNtOpenTimer)( PHANDLE, ACCESS_MASK, const POBJECT_ATTRIBUTES ); static NTSTATUS (WINAPI *pNtCreateSection)( PHANDLE, ACCESS_MASK, const POBJECT_ATTRIBUTES, const PLARGE_INTEGER, ULONG, ULONG, HANDLE ); +static NTSTATUS (WINAPI *pNtOpenSection)( PHANDLE, ACCESS_MASK, POBJECT_ATTRIBUTES ); static NTSTATUS (WINAPI *pNtOpenFile) ( PHANDLE, ACCESS_MASK, POBJECT_ATTRIBUTES, PIO_STATUS_BLOCK, ULONG, ULONG ); static NTSTATUS (WINAPI *pNtClose) ( HANDLE ); static NTSTATUS (WINAPI *pNtCreateNamedPipeFile)( PHANDLE, ULONG, POBJECT_ATTRIBUTES, PIO_STATUS_BLOCK, @@ -55,6 +66,7 @@ static NTSTATUS (WINAPI *pNtWaitForKeyedEvent)( HANDLE, const void *, BOOLEAN, const LARGE_INTEGER * ); static NTSTATUS (WINAPI *pNtReleaseKeyedEvent)( HANDLE, const void *, BOOLEAN, const LARGE_INTEGER * ); static NTSTATUS (WINAPI *pNtCreateIoCompletion)(PHANDLE, ACCESS_MASK, POBJECT_ATTRIBUTES, ULONG); +static NTSTATUS (WINAPI *pNtOpenIoCompletion)( PHANDLE, ACCESS_MASK, POBJECT_ATTRIBUTES ); #define KEYEDEVENT_WAIT 0x0001 #define KEYEDEVENT_WAKE 0x0002 @@ -165,6 +177,16 @@ status == STATUS_OBJECT_NAME_INVALID, /* vista */ "NtOpenFile should have failed with STATUS_OBJECT_NAME_NOT_FOUND got(%08x)\n", status); + str.Length -= 4 * sizeof(WCHAR); + status = pNtOpenFile(&h, GENERIC_READ, &attr, &iosb, FILE_SHARE_READ|FILE_SHARE_WRITE, 0); + ok(status == STATUS_SUCCESS, "NtOpenFile should have succeeded got %08x\n", status); + pNtClose( h ); + + str.Length -= sizeof(WCHAR); + status = pNtOpenFile(&h, GENERIC_READ, &attr, &iosb, FILE_SHARE_READ|FILE_SHARE_WRITE, 0); + ok(status == STATUS_SUCCESS, "NtOpenFile should have succeeded got %08x\n", status); + pNtClose( h ); + pNtClose(pipe); } @@ -171,28 +193,19 @@ #define DIRECTORY_QUERY (0x0001) #define SYMBOLIC_LINK_QUERY 0x0001 -#define DIR_TEST_CREATE_FAILURE(h,e) \ - status = pNtCreateDirectoryObject(h, DIRECTORY_QUERY, &attr);\ - ok(status == e,"NtCreateDirectoryObject should have failed with %s got(%08x)\n", #e, status); -#define DIR_TEST_OPEN_FAILURE(h,e) \ - status = pNtOpenDirectoryObject(h, DIRECTORY_QUERY, &attr);\ - ok(status == e,"NtOpenDirectoryObject should have failed with %s got(%08x)\n", #e, status); -#define DIR_TEST_CREATE_OPEN_FAILURE(h,n,e) \ - pRtlCreateUnicodeStringFromAsciiz(&str, n);\ - DIR_TEST_CREATE_FAILURE(h,e) DIR_TEST_OPEN_FAILURE(h,e)\ - pRtlFreeUnicodeString(&str); +#define DIR_TEST_CREATE_OPEN(n,e) \ + do { \ + HANDLE h; \ + pRtlCreateUnicodeStringFromAsciiz(&str, n); \ + status = pNtCreateDirectoryObject( &h, DIRECTORY_QUERY, &attr ); \ + ok( status == e, "NtCreateDirectoryObject(%s) got %08x\n", n, status ); \ + if (!status) pNtClose( h ); \ + status = pNtOpenDirectoryObject( &h, DIRECTORY_QUERY, &attr ); \ + ok( status == e, "NtOpenDirectoryObject(%s) got %08x\n", n, status ); \ + if (!status) pNtClose( h ); \ + pRtlFreeUnicodeString(&str); \ + } while(0) -#define DIR_TEST_CREATE_SUCCESS(h) \ - status = pNtCreateDirectoryObject(h, DIRECTORY_QUERY, &attr); \ - ok(status == STATUS_SUCCESS, "Failed to create Directory(%08x)\n", status); -#define DIR_TEST_OPEN_SUCCESS(h) \ - status = pNtOpenDirectoryObject(h, DIRECTORY_QUERY, &attr); \ - ok(status == STATUS_SUCCESS, "Failed to open Directory(%08x)\n", status); -#define DIR_TEST_CREATE_OPEN_SUCCESS(h,n) \ - pRtlCreateUnicodeStringFromAsciiz(&str, n);\ - DIR_TEST_CREATE_SUCCESS(&h) pNtClose(h); DIR_TEST_OPEN_SUCCESS(&h) pNtClose(h); \ - pRtlFreeUnicodeString(&str); - static BOOL is_correct_dir( HANDLE dir, const char *name ) { NTSTATUS status; @@ -262,10 +275,12 @@ InitializeObjectAttributes(&attr, &str, 0, 0, NULL); pRtlCreateUnicodeStringFromAsciiz(&str, "\\"); - DIR_TEST_CREATE_FAILURE(&h, STATUS_OBJECT_NAME_COLLISION) + status = pNtCreateDirectoryObject( &h, DIRECTORY_QUERY, &attr ); + ok( status == STATUS_OBJECT_NAME_COLLISION, "NtCreateDirectoryObject got %08x\n", status ); InitializeObjectAttributes(&attr, &str, OBJ_OPENIF, 0, NULL); - DIR_TEST_CREATE_FAILURE(&h, STATUS_OBJECT_NAME_EXISTS) + status = pNtCreateDirectoryObject( &h, DIRECTORY_QUERY, &attr ); + ok( status == STATUS_OBJECT_NAME_EXISTS, "NtCreateDirectoryObject got %08x\n", status ); pNtClose(h); status = pNtCreateMutant(&h, GENERIC_ALL, &attr, FALSE); ok(status == STATUS_OBJECT_TYPE_MISMATCH, @@ -356,12 +371,529 @@ pNtClose(dir); } +static void test_all_kernel_objects( UINT line, OBJECT_ATTRIBUTES *attr, + NTSTATUS create_expect, NTSTATUS open_expect ) +{ + UNICODE_STRING target; + LARGE_INTEGER size; + NTSTATUS status, status2; + HANDLE ret, ret2; + + pRtlCreateUnicodeStringFromAsciiz( &target, "\\DosDevices" ); + size.QuadPart = 4096; + + status = pNtCreateMutant( &ret, GENERIC_ALL, attr, FALSE ); + ok( status == create_expect, "%u: NtCreateMutant failed %x\n", line, status ); + status2 = pNtOpenMutant( &ret2, GENERIC_ALL, attr ); + ok( status2 == open_expect, "%u: NtOpenMutant failed %x\n", line, status2 ); + if (!status) pNtClose( ret ); + if (!status2) pNtClose( ret2 ); + status = pNtCreateSemaphore( &ret, GENERIC_ALL, attr, 1, 2 ); + ok( status == create_expect, "%u: NtCreateSemaphore failed %x\n", line, status ); + status2 = pNtOpenSemaphore( &ret2, GENERIC_ALL, attr ); + ok( status2 == open_expect, "%u: NtOpenSemaphore failed %x\n", line, status2 ); + if (!status) pNtClose( ret ); + if (!status2) pNtClose( ret2 ); + status = pNtCreateEvent( &ret, GENERIC_ALL, attr, 1, 0 ); + ok( status == create_expect, "%u: NtCreateEvent failed %x\n", line, status ); + status2 = pNtOpenEvent( &ret2, GENERIC_ALL, attr ); + ok( status2 == open_expect, "%u: NtOpenEvent failed %x\n", line, status2 ); + if (!status) pNtClose( ret ); + if (!status2) pNtClose( ret2 ); + status = pNtCreateKeyedEvent( &ret, GENERIC_ALL, attr, 0 ); + ok( status == create_expect, "%u: NtCreateKeyedEvent failed %x\n", line, status ); + status2 = pNtOpenKeyedEvent( &ret2, GENERIC_ALL, attr ); + ok( status2 == open_expect, "%u: NtOpenKeyedEvent failed %x\n", line, status2 ); + if (!status) pNtClose( ret ); + if (!status2) pNtClose( ret2 ); + status = pNtCreateTimer( &ret, GENERIC_ALL, attr, NotificationTimer ); + ok( status == create_expect, "%u: NtCreateTimer failed %x\n", line, status ); + status2 = pNtOpenTimer( &ret2, GENERIC_ALL, attr ); + ok( status2 == open_expect, "%u: NtOpenTimer failed %x\n", line, status2 ); + if (!status) pNtClose( ret ); + if (!status2) pNtClose( ret2 ); + status = pNtCreateIoCompletion( &ret, GENERIC_ALL, attr, 0 ); + ok( status == create_expect, "%u: NtCreateCompletion failed %x\n", line, status ); + status2 = pNtOpenIoCompletion( &ret2, GENERIC_ALL, attr ); + ok( status2 == open_expect, "%u: NtOpenCompletion failed %x\n", line, status2 ); + if (!status) pNtClose( ret ); + if (!status2) pNtClose( ret2 ); + status = pNtCreateJobObject( &ret, GENERIC_ALL, attr ); + ok( status == create_expect, "%u: NtCreateJobObject failed %x\n", line, status ); + status2 = pNtOpenJobObject( &ret2, GENERIC_ALL, attr ); + ok( status2 == open_expect, "%u: NtOpenJobObject failed %x\n", line, status2 ); + if (!status) pNtClose( ret ); + if (!status2) pNtClose( ret2 ); + status = pNtCreateDirectoryObject( &ret, GENERIC_ALL, attr ); + ok( status == create_expect, "%u: NtCreateDirectoryObject failed %x\n", line, status ); + status2 = pNtOpenDirectoryObject( &ret2, GENERIC_ALL, attr ); + ok( status2 == open_expect, "%u: NtOpenDirectoryObject failed %x\n", line, status2 ); + if (!status) pNtClose( ret ); + if (!status2) pNtClose( ret2 ); + status = pNtCreateSymbolicLinkObject( &ret, GENERIC_ALL, attr, &target ); + ok( status == create_expect, "%u: NtCreateSymbolicLinkObject failed %x\n", line, status ); + status2 = pNtOpenSymbolicLinkObject( &ret2, GENERIC_ALL, attr ); + ok( status2 == open_expect, "%u: NtOpenSymbolicLinkObject failed %x\n", line, status2 ); + if (!status) pNtClose( ret ); + if (!status2) pNtClose( ret2 ); + status = pNtCreateSection( &ret, SECTION_MAP_WRITE, attr, &size, PAGE_READWRITE, SEC_COMMIT, 0 ); + ok( status == create_expect, "%u: NtCreateSection failed %x\n", line, status ); + status2 = pNtOpenSection( &ret2, SECTION_MAP_WRITE, attr ); + ok( status2 == open_expect, "%u: NtOpenSection failed %x\n", line, status2 ); + if (!status) pNtClose( ret ); + if (!status2) pNtClose( ret2 ); + pRtlFreeUnicodeString( &target ); +} + +static void test_name_limits(void) +{ + static const WCHAR localW[] = {'\\','B','a','s','e','N','a','m','e','d','O','b','j','e','c','t','s','\\','L','o','c','a','l',0}; + static const WCHAR pipeW[] = {'\\','D','e','v','i','c','e','\\','N','a','m','e','d','P','i','p','e','\\'}; + static const WCHAR mailslotW[] = {'\\','D','e','v','i','c','e','\\','M','a','i','l','S','l','o','t','\\'}; + static const WCHAR registryW[] = {'\\','R','E','G','I','S','T','R','Y','\\','M','a','c','h','i','n','e','\\','S','O','F','T','W','A','R','E','\\','M','i','c','r','o','s','o','f','t','\\'}; + OBJECT_ATTRIBUTES attr, attr2, attr3; + IO_STATUS_BLOCK iosb; + LARGE_INTEGER size, timeout; + UNICODE_STRING str, str2, target; + NTSTATUS status; + HANDLE ret, ret2; + DWORD i; + + InitializeObjectAttributes( &attr, &str, 0, 0, NULL ); + InitializeObjectAttributes( &attr2, &str, 0, (HANDLE)0xdeadbeef, NULL ); + InitializeObjectAttributes( &attr3, &str, 0, 0, NULL ); + str.Buffer = HeapAlloc( GetProcessHeap(), 0, 65536 + sizeof(registryW)); + str.MaximumLength = 65534; + for (i = 0; i < 65536 / sizeof(WCHAR); i++) str.Buffer[i] = 'a'; + size.QuadPart = 4096; + pRtlCreateUnicodeStringFromAsciiz( &target, "\\DosDevices" ); + + if (!(attr.RootDirectory = get_base_dir())) + { + win_skip( "couldn't find the BaseNamedObjects dir\n" ); + return; + } + + str.Length = 0; + status = pNtCreateMutant( &ret, GENERIC_ALL, &attr2, FALSE ); + ok( status == STATUS_SUCCESS, "%u: NtCreateMutant failed %x\n", str.Length, status ); + attr3.RootDirectory = ret; + status = pNtOpenMutant( &ret2, GENERIC_ALL, &attr ); + ok( status == STATUS_OBJECT_TYPE_MISMATCH, "%u: NtOpenMutant failed %x\n", str.Length, status ); + status = pNtOpenMutant( &ret2, GENERIC_ALL, &attr3 ); + ok( status == STATUS_OBJECT_TYPE_MISMATCH || status == STATUS_INVALID_HANDLE, + "%u: NtOpenMutant failed %x\n", str.Length, status ); + pNtClose( ret ); + status = pNtCreateSemaphore( &ret, GENERIC_ALL, &attr2, 1, 2 ); + ok( status == STATUS_SUCCESS, "%u: NtCreateSemaphore failed %x\n", str.Length, status ); + attr3.RootDirectory = ret; + status = pNtOpenSemaphore( &ret2, GENERIC_ALL, &attr ); + ok( status == STATUS_OBJECT_TYPE_MISMATCH, "%u: NtOpenSemaphore failed %x\n", str.Length, status ); + status = pNtOpenSemaphore( &ret2, GENERIC_ALL, &attr3 ); + ok( status == STATUS_OBJECT_TYPE_MISMATCH || status == STATUS_INVALID_HANDLE, + "%u: NtOpenSemaphore failed %x\n", str.Length, status ); + pNtClose( ret ); + status = pNtCreateEvent( &ret, GENERIC_ALL, &attr2, 1, 0 ); + ok( status == STATUS_SUCCESS, "%u: NtCreateEvent failed %x\n", str.Length, status ); + attr3.RootDirectory = ret; + status = pNtOpenEvent( &ret2, GENERIC_ALL, &attr ); + ok( status == STATUS_OBJECT_TYPE_MISMATCH, "%u: NtOpenEvent failed %x\n", str.Length, status ); + status = pNtOpenEvent( &ret2, GENERIC_ALL, &attr3 ); + ok( status == STATUS_OBJECT_TYPE_MISMATCH || status == STATUS_INVALID_HANDLE, + "%u: NtOpenEvent failed %x\n", str.Length, status ); + pNtClose( ret ); + status = pNtCreateKeyedEvent( &ret, GENERIC_ALL, &attr2, 0 ); + ok( status == STATUS_SUCCESS, "%u: NtCreateKeyedEvent failed %x\n", str.Length, status ); + attr3.RootDirectory = ret; + status = pNtOpenKeyedEvent( &ret2, GENERIC_ALL, &attr ); + ok( status == STATUS_OBJECT_TYPE_MISMATCH, "%u: NtOpenKeyedEvent failed %x\n", str.Length, status ); + status = pNtOpenKeyedEvent( &ret2, GENERIC_ALL, &attr3 ); + ok( status == STATUS_OBJECT_TYPE_MISMATCH || status == STATUS_INVALID_HANDLE, + "%u: NtOpenKeyedEvent failed %x\n", str.Length, status ); + pNtClose( ret ); + status = pNtCreateTimer( &ret, GENERIC_ALL, &attr2, NotificationTimer ); + ok( status == STATUS_SUCCESS, "%u: NtCreateTimer failed %x\n", str.Length, status ); + attr3.RootDirectory = ret; + status = pNtOpenTimer( &ret2, GENERIC_ALL, &attr ); + ok( status == STATUS_OBJECT_TYPE_MISMATCH, "%u: NtOpenTimer failed %x\n", str.Length, status ); + status = pNtOpenTimer( &ret2, GENERIC_ALL, &attr3 ); + ok( status == STATUS_OBJECT_TYPE_MISMATCH || status == STATUS_INVALID_HANDLE, + "%u: NtOpenTimer failed %x\n", str.Length, status ); + pNtClose( ret ); + status = pNtCreateIoCompletion( &ret, GENERIC_ALL, &attr2, 0 ); + ok( status == STATUS_SUCCESS, "%u: NtCreateCompletion failed %x\n", str.Length, status ); + attr3.RootDirectory = ret; + status = pNtOpenIoCompletion( &ret2, GENERIC_ALL, &attr ); + ok( status == STATUS_OBJECT_TYPE_MISMATCH, "%u: NtOpenCompletion failed %x\n", str.Length, status ); + status = pNtOpenIoCompletion( &ret2, GENERIC_ALL, &attr3 ); + ok( status == STATUS_OBJECT_TYPE_MISMATCH || status == STATUS_INVALID_HANDLE, + "%u: NtOpenCompletion failed %x\n", str.Length, status ); + pNtClose( ret ); + status = pNtCreateJobObject( &ret, GENERIC_ALL, &attr2 ); + ok( status == STATUS_SUCCESS, "%u: NtCreateJobObject failed %x\n", str.Length, status ); + attr3.RootDirectory = ret; + status = pNtOpenJobObject( &ret2, GENERIC_ALL, &attr ); + ok( status == STATUS_OBJECT_TYPE_MISMATCH, "%u: NtOpenJobObject failed %x\n", str.Length, status ); + status = pNtOpenJobObject( &ret2, GENERIC_ALL, &attr3 ); + ok( status == STATUS_OBJECT_TYPE_MISMATCH || status == STATUS_INVALID_HANDLE, + "%u: NtOpenJobObject failed %x\n", str.Length, status ); + pNtClose( ret ); + status = pNtCreateDirectoryObject( &ret, GENERIC_ALL, &attr2 ); + ok( status == STATUS_SUCCESS, "%u: NtCreateDirectoryObject failed %x\n", str.Length, status ); + attr3.RootDirectory = ret; + status = pNtOpenDirectoryObject( &ret2, GENERIC_ALL, &attr ); + ok( status == STATUS_SUCCESS || broken(status == STATUS_ACCESS_DENIED), /* winxp */ + "%u: NtOpenDirectoryObject failed %x\n", str.Length, status ); + if (!status) pNtClose( ret2 ); + status = pNtOpenDirectoryObject( &ret2, GENERIC_ALL, &attr3 ); + ok( status == STATUS_SUCCESS, "%u: NtOpenDirectoryObject failed %x\n", str.Length, status ); + pNtClose( ret2 ); + pNtClose( ret ); + status = pNtCreateSymbolicLinkObject( &ret, GENERIC_ALL, &attr2, &target ); + ok( status == STATUS_SUCCESS, "%u: NtCreateSymbolicLinkObject failed %x\n", str.Length, status ); + attr3.RootDirectory = ret; + status = pNtOpenSymbolicLinkObject( &ret2, GENERIC_ALL, &attr ); + ok( status == STATUS_OBJECT_TYPE_MISMATCH, "%u: NtOpenSymbolicLinkObject failed %x\n", str.Length, status ); + status = pNtOpenSymbolicLinkObject( &ret2, GENERIC_ALL, &attr3 ); + ok( status == STATUS_SUCCESS, "%u: NtOpenSymbolicLinkObject failed %x\n", str.Length, status ); + pNtClose( ret2 ); + pNtClose( ret ); + status = pNtCreateSection( &ret, SECTION_MAP_WRITE, &attr2, &size, PAGE_READWRITE, SEC_COMMIT, 0 ); + ok( status == STATUS_SUCCESS, "%u: NtCreateSection failed %x\n", str.Length, status ); + attr3.RootDirectory = ret; + status = pNtOpenSection( &ret2, SECTION_MAP_WRITE, &attr ); + ok( status == STATUS_OBJECT_TYPE_MISMATCH, "%u: NtOpenSection failed %x\n", str.Length, status ); + status = pNtOpenSection( &ret2, SECTION_MAP_WRITE, &attr3 ); + ok( status == STATUS_OBJECT_TYPE_MISMATCH || status == STATUS_INVALID_HANDLE, + "%u: NtOpenSection failed %x\n", str.Length, status ); + pNtClose( ret ); + + str.Length = 67; + test_all_kernel_objects( __LINE__, &attr2, STATUS_OBJECT_NAME_INVALID, STATUS_OBJECT_NAME_INVALID ); + + str.Length = 65532; + test_all_kernel_objects( __LINE__, &attr, STATUS_SUCCESS, STATUS_SUCCESS ); + + str.Length = 65534; + test_all_kernel_objects( __LINE__, &attr, STATUS_OBJECT_NAME_INVALID, STATUS_OBJECT_NAME_INVALID ); + + str.Length = 128; + for (attr.Length = 0; attr.Length <= 2 * sizeof(attr); attr.Length++) + { + if (attr.Length == sizeof(attr)) + test_all_kernel_objects( __LINE__, &attr, STATUS_SUCCESS, STATUS_SUCCESS ); + else + test_all_kernel_objects( __LINE__, &attr, STATUS_INVALID_PARAMETER, STATUS_INVALID_PARAMETER ); + } + attr.Length = sizeof(attr); + + /* null attributes or ObjectName, with or without RootDirectory */ + attr3.RootDirectory = 0; + attr2.ObjectName = attr3.ObjectName = NULL; + test_all_kernel_objects( __LINE__, &attr2, STATUS_OBJECT_NAME_INVALID, STATUS_OBJECT_NAME_INVALID ); + test_all_kernel_objects( __LINE__, &attr3, STATUS_SUCCESS, STATUS_OBJECT_PATH_SYNTAX_BAD ); + + attr3.ObjectName = &str2; + pRtlInitUnicodeString( &str2, localW ); + status = pNtOpenSymbolicLinkObject( &ret, SYMBOLIC_LINK_QUERY, &attr3 ); + ok( status == STATUS_SUCCESS, "can't open BaseNamedObjects\\Local %x\n", status ); + attr3.ObjectName = &str; + attr3.RootDirectory = ret; + test_all_kernel_objects( __LINE__, &attr3, STATUS_OBJECT_TYPE_MISMATCH, STATUS_OBJECT_TYPE_MISMATCH ); + pNtClose( attr3.RootDirectory ); + + status = pNtCreateMutant( &ret, GENERIC_ALL, NULL, FALSE ); + ok( status == STATUS_SUCCESS, "NULL: NtCreateMutant failed %x\n", status ); + pNtClose( ret ); + status = pNtOpenMutant( &ret, GENERIC_ALL, NULL ); + ok( status == STATUS_INVALID_PARAMETER, "NULL: NtOpenMutant failed %x\n", status ); + status = pNtCreateSemaphore( &ret, GENERIC_ALL, NULL, 1, 2 ); + ok( status == STATUS_SUCCESS, "NULL: NtCreateSemaphore failed %x\n", status ); + pNtClose( ret ); + status = pNtOpenSemaphore( &ret, GENERIC_ALL, NULL ); + ok( status == STATUS_INVALID_PARAMETER, "NULL: NtOpenSemaphore failed %x\n", status ); + status = pNtCreateEvent( &ret, GENERIC_ALL, NULL, 1, 0 ); + ok( status == STATUS_SUCCESS, "NULL: NtCreateEvent failed %x\n", status ); + pNtClose( ret ); + status = pNtOpenEvent( &ret, GENERIC_ALL, NULL ); + ok( status == STATUS_INVALID_PARAMETER, "NULL: NtOpenEvent failed %x\n", status ); + status = pNtCreateKeyedEvent( &ret, GENERIC_ALL, NULL, 0 ); + ok( status == STATUS_SUCCESS, "NULL: NtCreateKeyedEvent failed %x\n", status ); + pNtClose( ret ); + status = pNtOpenKeyedEvent( &ret, GENERIC_ALL, NULL ); + ok( status == STATUS_INVALID_PARAMETER, "NULL: NtOpenKeyedEvent failed %x\n", status ); + status = pNtCreateTimer( &ret, GENERIC_ALL, NULL, NotificationTimer ); + ok( status == STATUS_SUCCESS, "NULL: NtCreateTimer failed %x\n", status ); + pNtClose( ret ); + status = pNtOpenTimer( &ret, GENERIC_ALL, NULL ); + ok( status == STATUS_INVALID_PARAMETER, "NULL: NtOpenTimer failed %x\n", status ); + status = pNtCreateIoCompletion( &ret, GENERIC_ALL, NULL, 0 ); + ok( status == STATUS_SUCCESS, "NULL: NtCreateCompletion failed %x\n", status ); + pNtClose( ret ); + status = pNtOpenIoCompletion( &ret, GENERIC_ALL, NULL ); + ok( status == STATUS_INVALID_PARAMETER, "NULL: NtOpenCompletion failed %x\n", status ); + status = pNtCreateJobObject( &ret, GENERIC_ALL, NULL ); + ok( status == STATUS_SUCCESS, "NULL: NtCreateJobObject failed %x\n", status ); + pNtClose( ret ); + status = pNtOpenJobObject( &ret, GENERIC_ALL, NULL ); + ok( status == STATUS_INVALID_PARAMETER, "NULL: NtOpenJobObject failed %x\n", status ); + status = pNtCreateDirectoryObject( &ret, GENERIC_ALL, NULL ); + ok( status == STATUS_SUCCESS, "NULL: NtCreateDirectoryObject failed %x\n", status ); + pNtClose( ret ); + status = pNtOpenDirectoryObject( &ret, GENERIC_ALL, NULL ); + ok( status == STATUS_INVALID_PARAMETER, "NULL: NtOpenDirectoryObject failed %x\n", status ); + status = pNtCreateSymbolicLinkObject( &ret, GENERIC_ALL, NULL, &target ); + ok( status == STATUS_ACCESS_VIOLATION || broken( status == STATUS_SUCCESS), /* winxp */ + "NULL: NtCreateSymbolicLinkObject failed %x\n", status ); + if (!status) pNtClose( ret ); + status = pNtOpenSymbolicLinkObject( &ret, GENERIC_ALL, NULL ); + ok( status == STATUS_INVALID_PARAMETER, "NULL: NtOpenSymbolicLinkObject failed %x\n", status ); + status = pNtCreateSection( &ret, SECTION_MAP_WRITE, NULL, &size, PAGE_READWRITE, SEC_COMMIT, 0 ); + ok( status == STATUS_SUCCESS, "NULL: NtCreateSection failed %x\n", status ); + pNtClose( ret ); + status = pNtOpenSection( &ret, SECTION_MAP_WRITE, NULL ); + ok( status == STATUS_INVALID_PARAMETER, "NULL: NtOpenSection failed %x\n", status ); + attr2.ObjectName = attr3.ObjectName = &str; + + /* named pipes */ + memcpy( str.Buffer, pipeW, sizeof(pipeW) ); + for (i = 0; i < 65536 / sizeof(WCHAR); i++) str.Buffer[i + sizeof(pipeW)/sizeof(WCHAR)] = 'a'; + str.Length = 0; + attr.RootDirectory = 0; + attr.Attributes = OBJ_CASE_INSENSITIVE; + timeout.QuadPart = -10000; + status = pNtCreateNamedPipeFile( &ret, GENERIC_ALL, &attr, &iosb, FILE_SHARE_READ|FILE_SHARE_WRITE, + FILE_CREATE, FILE_PIPE_FULL_DUPLEX, 0, 0, 0, 1, 256, 256, &timeout ); + ok( status == STATUS_OBJECT_PATH_SYNTAX_BAD, "%u: NtCreateNamedPipeFile failed %x\n", str.Length, status ); + status = pNtCreateNamedPipeFile( &ret, GENERIC_ALL, &attr2, &iosb, FILE_SHARE_READ|FILE_SHARE_WRITE, + FILE_CREATE, FILE_PIPE_FULL_DUPLEX, 0, 0, 0, 1, 256, 256, &timeout ); + ok( status == STATUS_INVALID_HANDLE, "%u: NtCreateNamedPipeFile failed %x\n", str.Length, status ); + str.Length = 67; + status = pNtCreateNamedPipeFile( &ret, GENERIC_ALL, &attr2, &iosb, FILE_SHARE_READ|FILE_SHARE_WRITE, + FILE_CREATE, FILE_PIPE_FULL_DUPLEX, 0, 0, 0, 1, 256, 256, &timeout ); + ok( status == STATUS_OBJECT_NAME_INVALID, "%u: NtCreateNamedPipeFile failed %x\n", str.Length, status ); + str.Length = 128; + for (attr.Length = 0; attr.Length <= 2 * sizeof(attr); attr.Length++) + { + status = pNtCreateNamedPipeFile( &ret, GENERIC_ALL, &attr, &iosb, FILE_SHARE_READ|FILE_SHARE_WRITE, + FILE_CREATE, FILE_PIPE_FULL_DUPLEX, 0, 0, 0, 1, 256, 256, &timeout ); + if (attr.Length == sizeof(attr)) + { + ok( status == STATUS_SUCCESS, "%u: NtCreateNamedPipeFile failed %x\n", str.Length, status ); + pNtClose( ret ); + } + else ok( status == STATUS_INVALID_PARAMETER, + "%u: NtCreateNamedPipeFile failed %x\n", str.Length, status ); + } + attr.Length = sizeof(attr); + str.Length = 65532; + status = pNtCreateNamedPipeFile( &ret, GENERIC_ALL, &attr, &iosb, FILE_SHARE_READ|FILE_SHARE_WRITE, + FILE_CREATE, FILE_PIPE_FULL_DUPLEX, 0, 0, 0, 1, 256, 256, &timeout ); + ok( status == STATUS_SUCCESS, "%u: NtCreateNamedPipeFile failed %x\n", str.Length, status ); + pNtClose( ret ); + str.Length = 65534; + status = pNtCreateNamedPipeFile( &ret, GENERIC_ALL, &attr, &iosb, FILE_SHARE_READ|FILE_SHARE_WRITE, + FILE_CREATE, FILE_PIPE_FULL_DUPLEX, 0, 0, 0, 1, 256, 256, &timeout ); + ok( status == STATUS_OBJECT_NAME_INVALID, "%u: NtCreateNamedPipeFile failed %x\n", str.Length, status ); + attr3.RootDirectory = 0; + attr2.ObjectName = attr3.ObjectName = NULL; + status = pNtCreateNamedPipeFile( &ret, GENERIC_ALL, &attr2, &iosb, FILE_SHARE_READ|FILE_SHARE_WRITE, + FILE_CREATE, FILE_PIPE_FULL_DUPLEX, 0, 0, 0, 1, 256, 256, &timeout ); + ok( status == STATUS_OBJECT_NAME_INVALID, "NULL: NtCreateNamedPipeFile failed %x\n", status ); + status = pNtCreateNamedPipeFile( &ret, GENERIC_ALL, &attr3, &iosb, FILE_SHARE_READ|FILE_SHARE_WRITE, + FILE_CREATE, FILE_PIPE_FULL_DUPLEX, 0, 0, 0, 1, 256, 256, &timeout ); + ok( status == STATUS_OBJECT_PATH_SYNTAX_BAD, "NULL: NtCreateNamedPipeFile failed %x\n", status ); + status = pNtCreateNamedPipeFile( &ret, GENERIC_ALL, NULL, &iosb, FILE_SHARE_READ|FILE_SHARE_WRITE, + FILE_CREATE, FILE_PIPE_FULL_DUPLEX, 0, 0, 0, 1, 256, 256, &timeout ); + ok( status == STATUS_INVALID_PARAMETER, "NULL: NtCreateNamedPipeFile failed %x\n", status ); + attr2.ObjectName = attr3.ObjectName = &str; + + /* mailslots */ + memcpy( str.Buffer, mailslotW, sizeof(mailslotW) ); + for (i = 0; i < 65536 / sizeof(WCHAR); i++) str.Buffer[i + sizeof(mailslotW)/sizeof(WCHAR)] = 'a'; + str.Length = 0; + status = pNtCreateMailslotFile( &ret, GENERIC_ALL, &attr, &iosb, 0, 0, 0, NULL ); + ok( status == STATUS_OBJECT_PATH_SYNTAX_BAD, "%u: NtCreateMailslotFile failed %x\n", str.Length, status ); + status = pNtCreateMailslotFile( &ret, GENERIC_ALL, &attr2, &iosb, 0, 0, 0, NULL ); + ok( status == STATUS_INVALID_HANDLE, "%u: NtCreateMailslotFile failed %x\n", str.Length, status ); + str.Length = 67; + status = pNtCreateMailslotFile( &ret, GENERIC_ALL, &attr2, &iosb, 0, 0, 0, NULL ); + ok( status == STATUS_OBJECT_NAME_INVALID, "%u: NtCreateMailslotFile failed %x\n", str.Length, status ); + str.Length = 128; + for (attr.Length = 0; attr.Length <= 2 * sizeof(attr); attr.Length++) + { + status = pNtCreateMailslotFile( &ret, GENERIC_ALL, &attr, &iosb, 0, 0, 0, NULL ); + if (attr.Length == sizeof(attr)) + { + ok( status == STATUS_SUCCESS, "%u: NtCreateMailslotFile failed %x\n", str.Length, status ); + pNtClose( ret ); + } + else ok( status == STATUS_INVALID_PARAMETER, + "%u: NtCreateMailslotFile failed %x\n", str.Length, status ); + } + attr.Length = sizeof(attr); + str.Length = 65532; + status = pNtCreateMailslotFile( &ret, GENERIC_ALL, &attr, &iosb, 0, 0, 0, NULL ); + ok( status == STATUS_SUCCESS, "%u: NtCreateMailslotFile failed %x\n", str.Length, status ); + pNtClose( ret ); + str.Length = 65534; + status = pNtCreateMailslotFile( &ret, GENERIC_ALL, &attr, &iosb, 0, 0, 0, NULL ); + ok( status == STATUS_OBJECT_NAME_INVALID, "%u: NtCreateMailslotFile failed %x\n", str.Length, status ); + attr3.RootDirectory = 0; + attr2.ObjectName = attr3.ObjectName = NULL; + status = pNtCreateMailslotFile( &ret, GENERIC_ALL, &attr2, &iosb, 0, 0, 0, NULL ); + ok( status == STATUS_OBJECT_NAME_INVALID, "NULL: NtCreateMailslotFile failed %x\n", status ); + status = pNtCreateMailslotFile( &ret, GENERIC_ALL, &attr3, &iosb, 0, 0, 0, NULL ); + ok( status == STATUS_OBJECT_PATH_SYNTAX_BAD, "NULL: NtCreateMailslotFile failed %x\n", status ); + status = pNtCreateMailslotFile( &ret, GENERIC_ALL, NULL, &iosb, 0, 0, 0, NULL ); + ok( status == STATUS_INVALID_PARAMETER, "NULL: NtCreateMailslotFile failed %x\n", status ); + attr2.ObjectName = attr3.ObjectName = &str; + + /* registry keys */ + memcpy( str.Buffer, registryW, sizeof(registryW) ); + for (i = 0; i < 65536 / sizeof(WCHAR); i++) str.Buffer[i + sizeof(registryW)/sizeof(WCHAR)] = 'a'; + str.Length = 0; + status = pNtCreateKey( &ret, GENERIC_ALL, &attr, 0, NULL, 0, NULL ); + todo_wine + ok( status == STATUS_OBJECT_PATH_SYNTAX_BAD, "%u: NtCreateKey failed %x\n", str.Length, status ); + status = pNtCreateKey( &ret, GENERIC_ALL, &attr2, 0, NULL, 0, NULL ); + ok( status == STATUS_INVALID_HANDLE, "%u: NtCreateKey failed %x\n", str.Length, status ); + status = pNtOpenKey( &ret, GENERIC_ALL, &attr2 ); + ok( status == STATUS_INVALID_HANDLE, "%u: NtOpenKey failed %x\n", str.Length, status ); + str.Length = sizeof(registryW) + 250 * sizeof(WCHAR) + 1; + status = pNtCreateKey( &ret, GENERIC_ALL, &attr, 0, NULL, 0, NULL ); + ok( status == STATUS_OBJECT_NAME_INVALID || + status == STATUS_INVALID_PARAMETER || + broken( status == STATUS_SUCCESS ), /* wow64 */ + "%u: NtCreateKey failed %x\n", str.Length, status ); + if (!status) + { + pNtDeleteKey( ret ); + pNtClose( ret ); + } + str.Length = sizeof(registryW) + 256 * sizeof(WCHAR); + status = pNtCreateKey( &ret, GENERIC_ALL, &attr, 0, NULL, 0, NULL ); + ok( status == STATUS_SUCCESS || status == STATUS_ACCESS_DENIED, + "%u: NtCreateKey failed %x\n", str.Length, status ); + if (!status) + { + status = pNtOpenKey( &ret2, KEY_READ, &attr ); + ok( status == STATUS_SUCCESS, "%u: NtOpenKey failed %x\n", str.Length, status ); + pNtClose( ret2 ); + attr3.RootDirectory = ret; + str.Length = 0; + status = pNtOpenKey( &ret2, KEY_READ, &attr3 ); + ok( status == STATUS_SUCCESS, "%u: NtOpenKey failed %x\n", str.Length, status ); + pNtClose( ret2 ); + pNtDeleteKey( ret ); + pNtClose( ret ); + + str.Length = sizeof(registryW) + 256 * sizeof(WCHAR); + for (attr.Length = 0; attr.Length <= 2 * sizeof(attr); attr.Length++) + { + if (attr.Length == sizeof(attr)) + { + status = pNtCreateKey( &ret, GENERIC_ALL, &attr, 0, NULL, 0, NULL ); + ok( status == STATUS_SUCCESS, "%u: NtCreateKey failed %x\n", str.Length, status ); + status = pNtOpenKey( &ret2, KEY_READ, &attr ); + ok( status == STATUS_SUCCESS, "%u: NtOpenKey failed %x\n", str.Length, status ); + pNtClose( ret2 ); + pNtDeleteKey( ret ); + pNtClose( ret ); + } + else + { + status = pNtCreateKey( &ret, GENERIC_ALL, &attr, 0, NULL, 0, NULL ); + ok( status == STATUS_INVALID_PARAMETER, "%u: NtCreateKey failed %x\n", str.Length, status ); + status = pNtOpenKey( &ret2, KEY_READ, &attr ); + ok( status == STATUS_INVALID_PARAMETER, "%u: NtOpenKey failed %x\n", str.Length, status ); + } + } + attr.Length = sizeof(attr); + } + str.Length = sizeof(registryW) + 256 * sizeof(WCHAR) + 1; + status = pNtCreateKey( &ret, GENERIC_ALL, &attr, 0, NULL, 0, NULL ); + ok( status == STATUS_OBJECT_NAME_INVALID || + status == STATUS_INVALID_PARAMETER || + broken( status == STATUS_SUCCESS ), /* win7 */ + "%u: NtCreateKey failed %x\n", str.Length, status ); + if (!status) + { + pNtDeleteKey( ret ); + pNtClose( ret ); + } + status = pNtOpenKey( &ret, GENERIC_ALL, &attr ); + ok( status == STATUS_OBJECT_NAME_INVALID || + status == STATUS_INVALID_PARAMETER || + broken( status == STATUS_OBJECT_NAME_NOT_FOUND ), /* wow64 */ + "%u: NtOpenKey failed %x\n", str.Length, status ); + str.Length++; + status = pNtCreateKey( &ret, GENERIC_ALL, &attr, 0, NULL, 0, NULL ); + ok( status == STATUS_INVALID_PARAMETER, "%u: NtCreateKey failed %x\n", str.Length, status ); + status = pNtOpenKey( &ret, GENERIC_ALL, &attr ); + todo_wine + ok( status == STATUS_INVALID_PARAMETER, "%u: NtOpenKey failed %x\n", str.Length, status ); + str.Length = 2000; + status = pNtCreateKey( &ret, GENERIC_ALL, &attr, 0, NULL, 0, NULL ); + ok( status == STATUS_INVALID_PARAMETER, "%u: NtCreateKey failed %x\n", str.Length, status ); + status = pNtOpenKey( &ret, GENERIC_ALL, &attr ); + todo_wine + ok( status == STATUS_INVALID_PARAMETER, "%u: NtOpenKey failed %x\n", str.Length, status ); + /* some Windows versions change the error past 2050 chars, others past 4066 chars, some don't */ + str.Length = 5000; + status = pNtCreateKey( &ret, GENERIC_ALL, &attr, 0, NULL, 0, NULL ); + ok( status == STATUS_BUFFER_OVERFLOW || + status == STATUS_BUFFER_TOO_SMALL || + status == STATUS_INVALID_PARAMETER, + "%u: NtCreateKey failed %x\n", str.Length, status ); + status = pNtOpenKey( &ret, GENERIC_ALL, &attr ); + todo_wine + ok( status == STATUS_BUFFER_OVERFLOW || + status == STATUS_BUFFER_TOO_SMALL || + status == STATUS_INVALID_PARAMETER, + "%u: NtOpenKey failed %x\n", str.Length, status ); + str.Length = 65534; + status = pNtCreateKey( &ret, GENERIC_ALL, &attr, 0, NULL, 0, NULL ); + ok( status == STATUS_OBJECT_NAME_INVALID || + status == STATUS_BUFFER_OVERFLOW || + status == STATUS_BUFFER_TOO_SMALL, + "%u: NtCreateKey failed %x\n", str.Length, status ); + status = pNtOpenKey( &ret, GENERIC_ALL, &attr ); + todo_wine + ok( status == STATUS_OBJECT_NAME_INVALID || + status == STATUS_BUFFER_OVERFLOW || + status == STATUS_BUFFER_TOO_SMALL, + "%u: NtOpenKey failed %x\n", str.Length, status ); + attr3.RootDirectory = 0; + attr2.ObjectName = attr3.ObjectName = NULL; + status = pNtCreateKey( &ret, GENERIC_ALL, &attr2, 0, NULL, 0, NULL ); + todo_wine + ok( status == STATUS_ACCESS_VIOLATION || status == STATUS_INVALID_HANDLE, + "NULL: NtCreateKey failed %x\n", status ); + status = pNtCreateKey( &ret, GENERIC_ALL, &attr3, 0, NULL, 0, NULL ); + todo_wine + ok( status == STATUS_ACCESS_VIOLATION, "NULL: NtCreateKey failed %x\n", status ); + status = pNtCreateKey( &ret, GENERIC_ALL, NULL, 0, NULL, 0, NULL ); + ok( status == STATUS_ACCESS_VIOLATION, "NULL: NtCreateKey failed %x\n", status ); + status = pNtOpenKey( &ret, GENERIC_ALL, &attr2 ); + ok( status == STATUS_ACCESS_VIOLATION || status == STATUS_INVALID_HANDLE, + "NULL: NtOpenKey failed %x\n", status ); + status = pNtOpenKey( &ret, GENERIC_ALL, &attr3 ); + ok( status == STATUS_ACCESS_VIOLATION, "NULL: NtOpenKey failed %x\n", status ); + status = pNtOpenKey( &ret, GENERIC_ALL, NULL ); + ok( status == STATUS_ACCESS_VIOLATION, "NULL: NtOpenKey failed %x\n", status ); + attr2.ObjectName = attr3.ObjectName = &str; + + pRtlFreeUnicodeString( &str ); + pRtlFreeUnicodeString( &target ); +} + static void test_directory(void) { NTSTATUS status; UNICODE_STRING str; OBJECT_ATTRIBUTES attr; - HANDLE dir, dir1, h; + HANDLE dir, dir1, h, h2; BOOL is_nt4; /* No name and/or no attributes */ @@ -380,28 +912,34 @@ "NtOpenDirectoryObject should have failed with STATUS_INVALID_PARAMETER got(%08x)\n", status); InitializeObjectAttributes(&attr, NULL, 0, 0, NULL); - DIR_TEST_CREATE_SUCCESS(&dir) - DIR_TEST_OPEN_FAILURE(&h, STATUS_OBJECT_PATH_SYNTAX_BAD) + status = pNtCreateDirectoryObject( &dir, DIRECTORY_QUERY, &attr ); + ok( status == STATUS_SUCCESS, "Failed to create directory %08x\n", status ); + status = pNtOpenDirectoryObject( &h, DIRECTORY_QUERY, &attr ); + ok( status == STATUS_OBJECT_PATH_SYNTAX_BAD, "NtOpenDirectoryObject got %08x\n", status ); /* Bad name */ InitializeObjectAttributes(&attr, &str, 0, 0, NULL); pRtlCreateUnicodeStringFromAsciiz(&str, ""); - DIR_TEST_CREATE_SUCCESS(&h) + status = pNtCreateDirectoryObject( &h, DIRECTORY_QUERY, &attr ); + ok( status == STATUS_SUCCESS, "Failed to create directory %08x\n", status ); pNtClose(h); - DIR_TEST_OPEN_FAILURE(&h, STATUS_OBJECT_PATH_SYNTAX_BAD) + status = pNtOpenDirectoryObject( &h, DIRECTORY_QUERY, &attr ); + ok( status == STATUS_OBJECT_PATH_SYNTAX_BAD, "NtOpenDirectoryObject got %08x\n", status ); pRtlFreeUnicodeString(&str); pNtClose(dir); - DIR_TEST_CREATE_OPEN_FAILURE(&h, "BaseNamedObjects", STATUS_OBJECT_PATH_SYNTAX_BAD) - DIR_TEST_CREATE_OPEN_FAILURE(&h, "\\BaseNamedObjects\\", STATUS_OBJECT_NAME_INVALID) - DIR_TEST_CREATE_OPEN_FAILURE(&h, "\\\\BaseNamedObjects", STATUS_OBJECT_NAME_INVALID) - DIR_TEST_CREATE_OPEN_FAILURE(&h, "\\BaseNamedObjects\\\\om.c-test", STATUS_OBJECT_NAME_INVALID) - DIR_TEST_CREATE_OPEN_FAILURE(&h, "\\BaseNamedObjects\\om.c-test\\", STATUS_OBJECT_PATH_NOT_FOUND) + DIR_TEST_CREATE_OPEN( "BaseNamedObjects", STATUS_OBJECT_PATH_SYNTAX_BAD ); + DIR_TEST_CREATE_OPEN( "\\BaseNamedObjects\\", STATUS_OBJECT_NAME_INVALID ); + DIR_TEST_CREATE_OPEN( "\\\\BaseNamedObjects", STATUS_OBJECT_NAME_INVALID ); + DIR_TEST_CREATE_OPEN( "\\BaseNamedObjects\\\\om.c-test", STATUS_OBJECT_NAME_INVALID ); + DIR_TEST_CREATE_OPEN( "\\BaseNamedObjects\\om.c-test\\", STATUS_OBJECT_PATH_NOT_FOUND ); pRtlCreateUnicodeStringFromAsciiz(&str, "\\BaseNamedObjects\\om.c-test"); - DIR_TEST_CREATE_SUCCESS(&h) - DIR_TEST_OPEN_SUCCESS(&dir1) + status = pNtCreateDirectoryObject( &h, DIRECTORY_QUERY, &attr ); + ok( status == STATUS_SUCCESS, "Failed to create directory %08x\n", status ); + status = pNtOpenDirectoryObject( &dir1, DIRECTORY_QUERY, &attr ); + ok( status == STATUS_SUCCESS, "Failed to open directory %08x\n", status ); pRtlFreeUnicodeString(&str); pNtClose(h); pNtClose(dir1); @@ -423,9 +961,43 @@ pRtlFreeUnicodeString(&str); InitializeObjectAttributes(&attr, &str, 0, dir, NULL); pRtlCreateUnicodeStringFromAsciiz(&str, "one more level"); - DIR_TEST_CREATE_FAILURE(&h, STATUS_OBJECT_TYPE_MISMATCH) + status = pNtCreateDirectoryObject( &h, DIRECTORY_QUERY, &attr ); + ok( status == STATUS_OBJECT_TYPE_MISMATCH, "NtCreateDirectoryObject got %08x\n", status ); pRtlFreeUnicodeString(&str); + pRtlCreateUnicodeStringFromAsciiz( &str, "\\BaseNamedObjects\\Local\\om.c-test" ); + InitializeObjectAttributes( &attr, &str, 0, 0, NULL ); + status = pNtCreateDirectoryObject( &dir1, DIRECTORY_QUERY, &attr ); + ok( status == STATUS_SUCCESS, "Failed to create directory %08x\n", status ); + pRtlFreeUnicodeString( &str ); + pRtlCreateUnicodeStringFromAsciiz( &str, "om.c-test" ); + InitializeObjectAttributes( &attr, &str, 0, dir, NULL ); + status = pNtOpenDirectoryObject( &h, DIRECTORY_QUERY, &attr ); + ok( status == STATUS_OBJECT_TYPE_MISMATCH, "Failed to open directory %08x\n", status ); + if (!status) pNtClose(h); + pRtlFreeUnicodeString( &str ); + + pRtlCreateUnicodeStringFromAsciiz( &str, "om.c-event" ); + InitializeObjectAttributes( &attr, &str, 0, dir1, NULL ); + status = pNtCreateEvent( &h, GENERIC_ALL, &attr, 1, 0 ); + ok( status == STATUS_SUCCESS, "NtCreateEvent failed %x\n", status ); + status = pNtOpenEvent( &h2, GENERIC_ALL, &attr ); + ok( status == STATUS_SUCCESS, "NtOpenEvent failed %x\n", status ); + pNtClose( h2 ); + pRtlFreeUnicodeString( &str ); + pRtlCreateUnicodeStringFromAsciiz( &str, "om.c-test\\om.c-event" ); + InitializeObjectAttributes( &attr, &str, 0, dir, NULL ); + status = pNtOpenEvent( &h2, GENERIC_ALL, &attr ); + ok( status == STATUS_OBJECT_TYPE_MISMATCH, "NtOpenEvent failed %x\n", status ); + pRtlFreeUnicodeString( &str ); + pRtlCreateUnicodeStringFromAsciiz( &str, "\\BasedNamedObjects\\Local\\om.c-test\\om.c-event" ); + InitializeObjectAttributes( &attr, &str, 0, 0, NULL ); + status = pNtOpenEvent( &h2, GENERIC_ALL, &attr ); + ok( status == STATUS_OBJECT_PATH_NOT_FOUND, "NtOpenEvent failed %x\n", status ); + pRtlFreeUnicodeString( &str ); + pNtClose( h ); + pNtClose( dir1 ); + str.Buffer = buffer; str.MaximumLength = sizeof(buffer); len = 0xdeadbeef; @@ -463,22 +1035,26 @@ pRtlCreateUnicodeStringFromAsciiz(&str, "\\BaseNamedObjects"); InitializeObjectAttributes(&attr, &str, 0, 0, NULL); - DIR_TEST_OPEN_SUCCESS(&dir) + status = pNtOpenDirectoryObject( &dir, DIRECTORY_QUERY, &attr ); + ok( status == STATUS_SUCCESS, "Failed to open directory %08x\n", status ); pRtlFreeUnicodeString(&str); InitializeObjectAttributes(&attr, NULL, 0, dir, NULL); - DIR_TEST_OPEN_FAILURE(&h, STATUS_OBJECT_NAME_INVALID) + status = pNtOpenDirectoryObject( &h, DIRECTORY_QUERY, &attr ); + ok( status == STATUS_OBJECT_NAME_INVALID, "NtOpenDirectoryObject got %08x\n", status ); InitializeObjectAttributes(&attr, &str, 0, dir, NULL); - DIR_TEST_CREATE_OPEN_SUCCESS(h, "") - DIR_TEST_CREATE_OPEN_FAILURE(&h, "\\", STATUS_OBJECT_PATH_SYNTAX_BAD) - DIR_TEST_CREATE_OPEN_FAILURE(&h, "\\om.c-test", STATUS_OBJECT_PATH_SYNTAX_BAD) - DIR_TEST_CREATE_OPEN_FAILURE(&h, "\\om.c-test\\", STATUS_OBJECT_PATH_SYNTAX_BAD) - DIR_TEST_CREATE_OPEN_FAILURE(&h, "om.c-test\\", STATUS_OBJECT_PATH_NOT_FOUND) + DIR_TEST_CREATE_OPEN( "", STATUS_SUCCESS ); + DIR_TEST_CREATE_OPEN( "\\", STATUS_OBJECT_PATH_SYNTAX_BAD ); + DIR_TEST_CREATE_OPEN( "\\om.c-test", STATUS_OBJECT_PATH_SYNTAX_BAD ); + DIR_TEST_CREATE_OPEN( "\\om.c-test\\", STATUS_OBJECT_PATH_SYNTAX_BAD ); + DIR_TEST_CREATE_OPEN( "om.c-test\\", STATUS_OBJECT_PATH_NOT_FOUND ); pRtlCreateUnicodeStringFromAsciiz(&str, "om.c-test"); - DIR_TEST_CREATE_SUCCESS(&dir1) - DIR_TEST_OPEN_SUCCESS(&h) + status = pNtCreateDirectoryObject( &dir1, DIRECTORY_QUERY, &attr ); + ok( status == STATUS_SUCCESS, "Failed to create directory %08x\n", status ); + status = pNtOpenDirectoryObject( &h, DIRECTORY_QUERY, &attr ); + ok( status == STATUS_SUCCESS, "Failed to open directory %08x\n", status ); pRtlFreeUnicodeString(&str); pNtClose(h); @@ -488,23 +1064,28 @@ /* Nested directories */ pRtlCreateUnicodeStringFromAsciiz(&str, "\\"); InitializeObjectAttributes(&attr, &str, 0, 0, NULL); - DIR_TEST_OPEN_SUCCESS(&dir) + status = pNtOpenDirectoryObject( &dir, DIRECTORY_QUERY, &attr ); + ok( status == STATUS_SUCCESS, "Failed to open directory %08x\n", status ); InitializeObjectAttributes(&attr, &str, 0, dir, NULL); - DIR_TEST_OPEN_FAILURE(&h, STATUS_OBJECT_PATH_SYNTAX_BAD) + status = pNtOpenDirectoryObject( &h, DIRECTORY_QUERY, &attr ); + ok( status == STATUS_OBJECT_PATH_SYNTAX_BAD, "NtOpenDirectoryObject got %08x\n", status ); pRtlFreeUnicodeString(&str); pNtClose(dir); InitializeObjectAttributes(&attr, &str, 0, 0, NULL); pRtlCreateUnicodeStringFromAsciiz(&str, "\\BaseNamedObjects\\om.c-test"); - DIR_TEST_CREATE_SUCCESS(&dir) + status = pNtCreateDirectoryObject( &dir, DIRECTORY_QUERY, &attr ); + ok( status == STATUS_SUCCESS, "Failed to create directory %08x\n", status ); pRtlFreeUnicodeString(&str); pRtlCreateUnicodeStringFromAsciiz(&str, "\\BaseNamedObjects\\om.c-test\\one more level"); - DIR_TEST_CREATE_SUCCESS(&h) + status = pNtCreateDirectoryObject( &h, DIRECTORY_QUERY, &attr ); + ok( status == STATUS_SUCCESS, "Failed to create directory %08x\n", status ); pRtlFreeUnicodeString(&str); pNtClose(h); InitializeObjectAttributes(&attr, &str, 0, dir, NULL); pRtlCreateUnicodeStringFromAsciiz(&str, "one more level"); - DIR_TEST_CREATE_SUCCESS(&h) + status = pNtCreateDirectoryObject( &h, DIRECTORY_QUERY, &attr ); + ok( status == STATUS_SUCCESS, "Failed to create directory %08x\n", status ); pRtlFreeUnicodeString(&str); pNtClose(h); @@ -514,15 +1095,18 @@ { InitializeObjectAttributes(&attr, &str, 0, 0, NULL); pRtlCreateUnicodeStringFromAsciiz(&str, "\\BaseNamedObjects\\Global\\om.c-test"); - DIR_TEST_CREATE_SUCCESS(&dir) + status = pNtCreateDirectoryObject( &dir, DIRECTORY_QUERY, &attr ); + ok( status == STATUS_SUCCESS, "Failed to create directory %08x\n", status ); pRtlFreeUnicodeString(&str); pRtlCreateUnicodeStringFromAsciiz(&str, "\\BaseNamedObjects\\Local\\om.c-test\\one more level"); - DIR_TEST_CREATE_SUCCESS(&h) + status = pNtCreateDirectoryObject( &h, DIRECTORY_QUERY, &attr ); + ok( status == STATUS_SUCCESS, "Failed to create directory %08x\n", status ); pRtlFreeUnicodeString(&str); pNtClose(h); InitializeObjectAttributes(&attr, &str, 0, dir, NULL); pRtlCreateUnicodeStringFromAsciiz(&str, "one more level"); - DIR_TEST_CREATE_SUCCESS(&dir) + status = pNtCreateDirectoryObject( &dir, DIRECTORY_QUERY, &attr ); + ok( status == STATUS_SUCCESS, "Failed to create directory %08x\n", status ); pRtlFreeUnicodeString(&str); pNtClose(h); pNtClose(dir); @@ -532,7 +1116,8 @@ InitializeObjectAttributes(&attr, &str, 0, 0, NULL); pRtlCreateUnicodeStringFromAsciiz(&str, "\\BaseNamedObjects"); - DIR_TEST_OPEN_SUCCESS(&dir) + status = pNtOpenDirectoryObject( &dir, DIRECTORY_QUERY, &attr ); + ok( status == STATUS_SUCCESS, "Failed to open directory %08x\n", status ); pRtlFreeUnicodeString(&str); InitializeObjectAttributes(&attr, &str, 0, dir, NULL); @@ -563,20 +1148,6 @@ pNtClose(dir); } -#define SYMLNK_TEST_CREATE_OPEN_FAILURE2(h,n,t,e,e2) \ - pRtlCreateUnicodeStringFromAsciiz(&str, n);\ - pRtlCreateUnicodeStringFromAsciiz(&target, t);\ - status = pNtCreateSymbolicLinkObject(h, SYMBOLIC_LINK_QUERY, &attr, &target);\ - ok(status == e || status == e2, \ - "NtCreateSymbolicLinkObject should have failed with %s or %s got(%08x)\n", #e, #e2, status);\ - status = pNtOpenSymbolicLinkObject(h, SYMBOLIC_LINK_QUERY, &attr);\ - ok(status == e || status == e2, \ - "NtOpenSymbolicLinkObject should have failed with %s or %s got(%08x)\n", #e, #e2, status);\ - pRtlFreeUnicodeString(&target);\ - pRtlFreeUnicodeString(&str); - -#define SYMLNK_TEST_CREATE_OPEN_FAILURE(h,n,t,e) SYMLNK_TEST_CREATE_OPEN_FAILURE2(h,n,t,e,e) - static void test_symboliclink(void) { NTSTATUS status; @@ -587,7 +1158,13 @@ /* No name and/or no attributes */ InitializeObjectAttributes(&attr, NULL, 0, 0, NULL); - SYMLNK_TEST_CREATE_OPEN_FAILURE2(NULL, "", "", STATUS_ACCESS_VIOLATION, STATUS_INVALID_PARAMETER) + pRtlCreateUnicodeStringFromAsciiz(&target, "\\DosDevices"); + status = pNtCreateSymbolicLinkObject( NULL, SYMBOLIC_LINK_QUERY, &attr, &target ); + ok( status == STATUS_ACCESS_VIOLATION || status == STATUS_INVALID_PARAMETER, + "NtCreateSymbolicLinkObject got %08x\n", status ); + status = pNtOpenSymbolicLinkObject( NULL, SYMBOLIC_LINK_QUERY, &attr ); + ok( status == STATUS_ACCESS_VIOLATION || status == STATUS_INVALID_PARAMETER, + "NtOpenSymbolicLinkObject got %08x\n", status ); status = pNtCreateSymbolicLinkObject(&h, SYMBOLIC_LINK_QUERY, NULL, NULL); ok(status == STATUS_ACCESS_VIOLATION, @@ -597,7 +1174,6 @@ "NtOpenSymbolicLinkObject should have failed with STATUS_INVALID_PARAMETER got(%08x)\n", status); /* No attributes */ - pRtlCreateUnicodeStringFromAsciiz(&target, "\\DosDevices"); status = pNtCreateSymbolicLinkObject(&h, SYMBOLIC_LINK_QUERY, NULL, &target); ok(status == STATUS_SUCCESS || status == STATUS_ACCESS_VIOLATION, /* nt4 */ "NtCreateSymbolicLinkObject failed(%08x)\n", status); @@ -634,14 +1210,46 @@ pRtlFreeUnicodeString(&str); pRtlFreeUnicodeString(&target); - SYMLNK_TEST_CREATE_OPEN_FAILURE(&h, "BaseNamedObjects", "->Somewhere", STATUS_OBJECT_PATH_SYNTAX_BAD) - SYMLNK_TEST_CREATE_OPEN_FAILURE(&h, "\\BaseNamedObjects\\", "->Somewhere", STATUS_OBJECT_NAME_INVALID) - SYMLNK_TEST_CREATE_OPEN_FAILURE(&h, "\\\\BaseNamedObjects", "->Somewhere", STATUS_OBJECT_NAME_INVALID) - SYMLNK_TEST_CREATE_OPEN_FAILURE(&h, "\\BaseNamedObjects\\\\om.c-test", "->Somewhere", STATUS_OBJECT_NAME_INVALID) - SYMLNK_TEST_CREATE_OPEN_FAILURE2(&h, "\\BaseNamedObjects\\om.c-test\\", "->Somewhere", - STATUS_OBJECT_NAME_INVALID, STATUS_OBJECT_PATH_NOT_FOUND) + pRtlCreateUnicodeStringFromAsciiz( &target, "->Somewhere"); + pRtlCreateUnicodeStringFromAsciiz( &str, "BaseNamedObjects" ); + status = pNtCreateSymbolicLinkObject( &h, SYMBOLIC_LINK_QUERY, &attr, &target ); + ok( status == STATUS_OBJECT_PATH_SYNTAX_BAD, "NtCreateSymbolicLinkObject got %08x\n", status ); + status = pNtOpenSymbolicLinkObject( &h, SYMBOLIC_LINK_QUERY, &attr ); + ok( status == STATUS_OBJECT_PATH_SYNTAX_BAD, "NtOpenSymbolicLinkObject got %08x\n", status ); + pRtlFreeUnicodeString( &str ); + pRtlCreateUnicodeStringFromAsciiz( &str, "\\BaseNamedObjects\\" ); + status = pNtCreateSymbolicLinkObject( &h, SYMBOLIC_LINK_QUERY, &attr, &target ); + ok( status == STATUS_OBJECT_NAME_INVALID, "NtCreateSymbolicLinkObject got %08x\n", status ); + status = pNtOpenSymbolicLinkObject( &h, SYMBOLIC_LINK_QUERY, &attr ); + ok( status == STATUS_OBJECT_NAME_INVALID, "NtOpenSymbolicLinkObject got %08x\n", status ); + pRtlFreeUnicodeString( &str ); + + pRtlCreateUnicodeStringFromAsciiz( &str, "\\\\BaseNamedObjects" ); + status = pNtCreateSymbolicLinkObject( &h, SYMBOLIC_LINK_QUERY, &attr, &target ); + ok( status == STATUS_OBJECT_NAME_INVALID, "NtCreateSymbolicLinkObject got %08x\n", status ); + status = pNtOpenSymbolicLinkObject( &h, SYMBOLIC_LINK_QUERY, &attr ); + ok( status == STATUS_OBJECT_NAME_INVALID, "NtOpenSymbolicLinkObject got %08x\n", status ); + pRtlFreeUnicodeString( &str ); + + pRtlCreateUnicodeStringFromAsciiz( &str, "\\BaseNamedObjects\\\\om.c-test" ); + status = pNtCreateSymbolicLinkObject( &h, SYMBOLIC_LINK_QUERY, &attr, &target ); + ok( status == STATUS_OBJECT_NAME_INVALID, "NtCreateSymbolicLinkObject got %08x\n", status ); + status = pNtOpenSymbolicLinkObject( &h, SYMBOLIC_LINK_QUERY, &attr ); + ok( status == STATUS_OBJECT_NAME_INVALID, "NtOpenSymbolicLinkObject got %08x\n", status ); + pRtlFreeUnicodeString( &str ); + + pRtlCreateUnicodeStringFromAsciiz( &str, "\\BaseNamedObjects\\om.c-test\\" ); + status = pNtCreateSymbolicLinkObject( &h, SYMBOLIC_LINK_QUERY, &attr, &target ); + ok( status == STATUS_OBJECT_NAME_INVALID || status == STATUS_OBJECT_PATH_NOT_FOUND, + "NtCreateSymbolicLinkObject got %08x\n", status ); + status = pNtOpenSymbolicLinkObject( &h, SYMBOLIC_LINK_QUERY, &attr ); + ok( status == STATUS_OBJECT_NAME_INVALID || status == STATUS_OBJECT_PATH_NOT_FOUND, + "NtOpenSymbolicLinkObject got %08x\n", status ); + pRtlFreeUnicodeString( &str ); + pRtlFreeUnicodeString(&target); + /* Compound test */ if (!(dir = get_base_dir())) { @@ -682,10 +1290,13 @@ char buffer[1024]; NTSTATUS status; ULONG len, expected_len; - UNICODE_STRING *str; + OBJECT_ATTRIBUTES attr; + UNICODE_STRING path, *str; char dir[MAX_PATH], tmp_path[MAX_PATH], file1[MAX_PATH + 16]; LARGE_INTEGER size; + InitializeObjectAttributes( &attr, &path, 0, 0, 0 ); + handle = CreateEventA( NULL, FALSE, FALSE, "test_event" ); len = 0; @@ -715,9 +1326,12 @@ str = (UNICODE_STRING *)buffer; ok( sizeof(UNICODE_STRING) + str->Length + sizeof(WCHAR) == len, "unexpected len %u\n", len ); ok( str->Length >= sizeof(name), "unexpected len %u\n", str->Length ); + ok( len > sizeof(UNICODE_STRING) + sizeof("\\test_event") * sizeof(WCHAR), + "name too short %s\n", wine_dbgstr_w(str->Buffer) ); /* there can be a \\Sessions prefix in the name */ ok( !memcmp( str->Buffer + (str->Length - sizeof(name)) / sizeof(WCHAR), name, sizeof(name) ), "wrong name %s\n", wine_dbgstr_w(str->Buffer) ); + trace( "got %s len %u\n", wine_dbgstr_w(str->Buffer), len ); len -= sizeof(WCHAR); status = pNtQueryObject( handle, ObjectNameInformation, buffer, len, &len ); @@ -851,6 +1465,64 @@ ok( str->Buffer && !memcmp( str->Buffer, type_section, sizeof(type_section) ), "wrong/bad type name %s (%p)\n", wine_dbgstr_w(str->Buffer), str->Buffer ); pNtClose( handle ); + + handle = CreateMailslotA( "\\\\.\\mailslot\\test_mailslot", 100, 1000, NULL ); + ok( handle != INVALID_HANDLE_VALUE, "CreateMailslot failed err %u\n", GetLastError() ); + len = 0; + status = pNtQueryObject( handle, ObjectNameInformation, buffer, sizeof(buffer), &len ); + ok( status == STATUS_SUCCESS , "NtQueryObject returned %x\n", status ); + str = (UNICODE_STRING *)buffer; + ok( len > sizeof(UNICODE_STRING), "unexpected len %u\n", len ); + str = (UNICODE_STRING *)buffer; + expected_len = sizeof(UNICODE_STRING) + str->Length + sizeof(WCHAR); + ok( len == expected_len || broken(len == expected_len - sizeof(WCHAR)), /* NT4 */ + "unexpected len %u\n", len ); + ok( len > sizeof(UNICODE_STRING) + sizeof("\\test_mailslot") * sizeof(WCHAR), + "name too short %s\n", wine_dbgstr_w(str->Buffer) ); + trace( "got %s len %u\n", wine_dbgstr_w(str->Buffer), len ); + pNtClose( handle ); + + handle = CreateNamedPipeA( "\\\\.\\pipe\\test_pipe", PIPE_ACCESS_DUPLEX, PIPE_READMODE_BYTE, + 1, 1000, 1000, 1000, NULL ); + ok( handle != INVALID_HANDLE_VALUE, "CreateNamedPipe failed err %u\n", GetLastError() ); + len = 0; + status = pNtQueryObject( handle, ObjectNameInformation, buffer, sizeof(buffer), &len ); + ok( status == STATUS_SUCCESS , "NtQueryObject returned %x\n", status ); + str = (UNICODE_STRING *)buffer; + ok( len > sizeof(UNICODE_STRING), "unexpected len %u\n", len ); + str = (UNICODE_STRING *)buffer; + expected_len = sizeof(UNICODE_STRING) + str->Length + sizeof(WCHAR); + ok( len == expected_len || broken(len == expected_len - sizeof(WCHAR)), /* NT4 */ + "unexpected len %u\n", len ); + ok( len > sizeof(UNICODE_STRING) + sizeof("\\test_pipe") * sizeof(WCHAR), + "name too short %s\n", wine_dbgstr_w(str->Buffer) ); + trace( "got %s len %u\n", wine_dbgstr_w(str->Buffer), len ); + pNtClose( handle ); + + pRtlCreateUnicodeStringFromAsciiz( &path, "\\REGISTRY\\Machine\\Software\\Classes" ); + status = pNtCreateKey( &handle, KEY_ALL_ACCESS, &attr, 0, 0, 0, 0 ); + ok( status == STATUS_SUCCESS || status == STATUS_ACCESS_DENIED, + "NtCreateKey failed status %x\n", status ); + pRtlFreeUnicodeString( &path ); + if (status == STATUS_SUCCESS) + { + len = 0; + status = pNtQueryObject( handle, ObjectNameInformation, buffer, sizeof(buffer), &len ); + ok( status == STATUS_SUCCESS , "NtQueryObject returned %x\n", status ); + str = (UNICODE_STRING *)buffer; + todo_wine + ok( len > sizeof(UNICODE_STRING), "unexpected len %u\n", len ); + str = (UNICODE_STRING *)buffer; + expected_len = sizeof(UNICODE_STRING) + str->Length + sizeof(WCHAR); + todo_wine + ok( len == expected_len || broken(len == expected_len - sizeof(WCHAR)), /* NT4 */ + "unexpected len %u\n", len ); + todo_wine + ok( len > sizeof(UNICODE_STRING) + sizeof("\\Classes") * sizeof(WCHAR), + "name too short %s\n", wine_dbgstr_w(str->Buffer) ); + trace( "got %s len %u\n", wine_dbgstr_w(str->Buffer), len ); + pNtClose( handle ); + } } static void test_type_mismatch(void) @@ -1206,6 +1878,12 @@ pRtlCreateUnicodeStringFromAsciiz = (void *)GetProcAddress(hntdll, "RtlCreateUnicodeStringFromAsciiz"); pRtlFreeUnicodeString = (void *)GetProcAddress(hntdll, "RtlFreeUnicodeString"); pNtCreateEvent = (void *)GetProcAddress(hntdll, "NtCreateEvent"); + pNtCreateJobObject = (void *)GetProcAddress(hntdll, "NtCreateJobObject"); + pNtOpenJobObject = (void *)GetProcAddress(hntdll, "NtOpenJobObject"); + pNtCreateKey = (void *)GetProcAddress(hntdll, "NtCreateKey"); + pNtOpenKey = (void *)GetProcAddress(hntdll, "NtOpenKey"); + pNtDeleteKey = (void *)GetProcAddress(hntdll, "NtDeleteKey"); + pNtCreateMailslotFile = (void *)GetProcAddress(hntdll, "NtCreateMailslotFile"); pNtCreateMutant = (void *)GetProcAddress(hntdll, "NtCreateMutant"); pNtOpenEvent = (void *)GetProcAddress(hntdll, "NtOpenEvent"); pNtQueryEvent = (void *)GetProcAddress(hntdll, "NtQueryEvent"); @@ -1221,8 +1899,11 @@ pNtCreateSymbolicLinkObject = (void *)GetProcAddress(hntdll, "NtCreateSymbolicLinkObject"); pNtQuerySymbolicLinkObject = (void *)GetProcAddress(hntdll, "NtQuerySymbolicLinkObject"); pNtCreateSemaphore = (void *)GetProcAddress(hntdll, "NtCreateSemaphore"); + pNtOpenSemaphore = (void *)GetProcAddress(hntdll, "NtOpenSemaphore"); pNtCreateTimer = (void *)GetProcAddress(hntdll, "NtCreateTimer"); + pNtOpenTimer = (void *)GetProcAddress(hntdll, "NtOpenTimer"); pNtCreateSection = (void *)GetProcAddress(hntdll, "NtCreateSection"); + pNtOpenSection = (void *)GetProcAddress(hntdll, "NtOpenSection"); pNtQueryObject = (void *)GetProcAddress(hntdll, "NtQueryObject"); pNtReleaseSemaphore = (void *)GetProcAddress(hntdll, "NtReleaseSemaphore"); pNtCreateKeyedEvent = (void *)GetProcAddress(hntdll, "NtCreateKeyedEvent"); @@ -1230,10 +1911,12 @@ pNtWaitForKeyedEvent = (void *)GetProcAddress(hntdll, "NtWaitForKeyedEvent"); pNtReleaseKeyedEvent = (void *)GetProcAddress(hntdll, "NtReleaseKeyedEvent"); pNtCreateIoCompletion = (void *)GetProcAddress(hntdll, "NtCreateIoCompletion"); + pNtOpenIoCompletion = (void *)GetProcAddress(hntdll, "NtOpenIoCompletion"); test_case_sensitive(); test_namespace_pipe(); test_name_collisions(); + test_name_limits(); test_directory(); test_symboliclink(); test_query_object(); Index: modules/rostests/winetests/ntdll/pipe.c =================================================================== --- modules/rostests/winetests/ntdll/pipe.c (revision 70979) +++ modules/rostests/winetests/ntdll/pipe.c (working copy) @@ -126,7 +126,7 @@ attr.SecurityDescriptor = NULL; attr.SecurityQualityOfService = NULL; - timeout.QuadPart = -100000000000ll; + timeout.QuadPart = -100000000; res = pNtCreateNamedPipeFile(handle, FILE_READ_ATTRIBUTES | SYNCHRONIZE, &attr, &iosb, sharing, 2 /*FILE_CREATE*/, options, 1, 0, 0, 0xFFFFFFFF, 500, 500, &timeout); @@ -152,7 +152,7 @@ attr.SecurityDescriptor = NULL; attr.SecurityQualityOfService = NULL; - timeout.QuadPart = -100000000000ll; + timeout.QuadPart = -100000000; /* create a pipe with FILE_OVERWRITE */ res = pNtCreateNamedPipeFile(&handle, FILE_READ_ATTRIBUTES | SYNCHRONIZE, &attr, &iosb, FILE_SHARE_READ, 4 /*FILE_OVERWRITE*/, @@ -521,7 +521,7 @@ attr.SecurityDescriptor = NULL; attr.SecurityQualityOfService = NULL; - timeout.QuadPart = -100000000000ll; + timeout.QuadPart = -100000000; /* test with INVALID_HANDLE_VALUE */ res = pNtQueryInformationFile(INVALID_HANDLE_VALUE, &iosb, &fpi, sizeof(fpi), (FILE_INFORMATION_CLASS)23); Index: modules/rostests/winetests/ntdll/reg.c =================================================================== --- modules/rostests/winetests/ntdll/reg.c (revision 70979) +++ modules/rostests/winetests/ntdll/reg.c (working copy) @@ -340,6 +340,7 @@ NTSTATUS status; OBJECT_ATTRIBUTES attr; ACCESS_MASK am = KEY_READ; + UNICODE_STRING str; /* All NULL */ status = pNtOpenKey(NULL, 0, NULL); @@ -361,6 +362,79 @@ status = pNtOpenKey(&key, am, &attr); ok(status == STATUS_INVALID_PARAMETER, "Expected STATUS_INVALID_PARAMETER, got: 0x%08x\n", status); + /* Calling without parent key requres full registry path. */ + pRtlCreateUnicodeStringFromAsciiz( &str, "Machine" ); + InitializeObjectAttributes(&attr, &str, 0, 0, 0); + status = pNtOpenKey(&key, KEY_READ, &attr); + todo_wine ok(status == STATUS_OBJECT_PATH_SYNTAX_BAD, "NtOpenKey Failed: 0x%08x\n", status); + pRtlFreeUnicodeString( &str ); + + /* Open is case sensitive unless OBJ_CASE_INSENSITIVE is specified. */ + pRtlCreateUnicodeStringFromAsciiz( &str, "\\Registry\\Machine" ); + status = pNtOpenKey(&key, KEY_READ, &attr); + todo_wine ok(status == STATUS_OBJECT_PATH_NOT_FOUND, "NtOpenKey Failed: 0x%08x\n", status); + + attr.Attributes = OBJ_CASE_INSENSITIVE; + status = pNtOpenKey(&key, KEY_READ, &attr); + ok(status == STATUS_SUCCESS, "NtOpenKey Failed: 0x%08x\n", status); + pNtClose(key); + pRtlFreeUnicodeString( &str ); + + pRtlCreateUnicodeStringFromAsciiz( &str, "" ); + status = pNtOpenKey(&key, KEY_READ, &attr); + todo_wine + ok( status == STATUS_OBJECT_PATH_SYNTAX_BAD, "NtOpenKey failed: 0x%08x\n", status ); + pRtlFreeUnicodeString( &str ); + + pRtlCreateUnicodeStringFromAsciiz( &str, "\\" ); + status = pNtOpenKey(&key, KEY_READ, &attr); + todo_wine + ok( status == STATUS_OBJECT_TYPE_MISMATCH, "NtOpenKey failed: 0x%08x\n", status ); + pRtlFreeUnicodeString( &str ); + + pRtlCreateUnicodeStringFromAsciiz( &str, "\\Registry" ); + status = pNtOpenKey(&key, KEY_READ, &attr); + todo_wine + ok( status == STATUS_SUCCESS, "NtOpenKey failed: 0x%08x\n", status ); + pNtClose( key ); + pRtlFreeUnicodeString( &str ); + + pRtlCreateUnicodeStringFromAsciiz( &str, "\\Registry\\" ); + status = pNtOpenKey(&key, KEY_READ, &attr); + ok( status == STATUS_SUCCESS, "NtOpenKey failed: 0x%08x\n", status ); + pNtClose( key ); + pRtlFreeUnicodeString( &str ); + + pRtlCreateUnicodeStringFromAsciiz( &str, "\\Foobar" ); + status = pNtOpenKey(&key, KEY_READ, &attr); + todo_wine + ok( status == STATUS_OBJECT_NAME_NOT_FOUND, "NtOpenKey failed: 0x%08x\n", status ); + pRtlFreeUnicodeString( &str ); + + pRtlCreateUnicodeStringFromAsciiz( &str, "\\Foobar\\Machine" ); + status = pNtOpenKey(&key, KEY_READ, &attr); + todo_wine + ok( status == STATUS_OBJECT_PATH_NOT_FOUND, "NtOpenKey failed: 0x%08x\n", status ); + pRtlFreeUnicodeString( &str ); + + pRtlCreateUnicodeStringFromAsciiz( &str, "\\Machine\\Software\\Classes" ); + status = pNtOpenKey(&key, KEY_READ, &attr); + todo_wine + ok( status == STATUS_OBJECT_PATH_NOT_FOUND, "NtOpenKey failed: 0x%08x\n", status ); + pRtlFreeUnicodeString( &str ); + + pRtlCreateUnicodeStringFromAsciiz( &str, "Machine\\Software\\Classes" ); + status = pNtOpenKey(&key, KEY_READ, &attr); + todo_wine + ok( status == STATUS_OBJECT_PATH_SYNTAX_BAD, "NtOpenKey failed: 0x%08x\n", status ); + pRtlFreeUnicodeString( &str ); + + pRtlCreateUnicodeStringFromAsciiz( &str, "\\Device\\Null" ); + status = pNtOpenKey(&key, KEY_READ, &attr); + todo_wine + ok( status == STATUS_OBJECT_TYPE_MISMATCH, "NtOpenKey failed: 0x%08x\n", status ); + pRtlFreeUnicodeString( &str ); + if (!pNtOpenKeyEx) { win_skip("NtOpenKeyEx not available\n"); @@ -455,6 +529,95 @@ pNtDeleteKey( subkey ); pNtClose( subkey ); + attr.RootDirectory = 0; + attr.Attributes = OBJ_CASE_INSENSITIVE; + + pRtlCreateUnicodeStringFromAsciiz( &str, "" ); + status = pNtCreateKey( &subkey, am, &attr, 0, 0, 0, 0 ); + todo_wine + ok( status == STATUS_OBJECT_PATH_SYNTAX_BAD, "NtCreateKey failed: 0x%08x\n", status ); + pRtlFreeUnicodeString( &str ); + + pRtlCreateUnicodeStringFromAsciiz( &str, "\\" ); + status = pNtCreateKey( &subkey, am, &attr, 0, 0, 0, 0 ); + todo_wine + ok( status == STATUS_OBJECT_TYPE_MISMATCH, "NtCreateKey failed: 0x%08x\n", status ); + pRtlFreeUnicodeString( &str ); + + pRtlCreateUnicodeStringFromAsciiz( &str, "\\Registry" ); + status = pNtCreateKey( &subkey, am, &attr, 0, 0, 0, 0 ); + todo_wine + ok( status == STATUS_SUCCESS || status == STATUS_ACCESS_DENIED, + "NtCreateKey failed: 0x%08x\n", status ); + if (!status) pNtClose( subkey ); + pRtlFreeUnicodeString( &str ); + + pRtlCreateUnicodeStringFromAsciiz( &str, "\\Registry\\" ); + status = pNtCreateKey( &subkey, am, &attr, 0, 0, 0, 0 ); + ok( status == STATUS_SUCCESS || status == STATUS_ACCESS_DENIED, + "NtCreateKey failed: 0x%08x\n", status ); + if (!status) pNtClose( subkey ); + pRtlFreeUnicodeString( &str ); + + pRtlCreateUnicodeStringFromAsciiz( &str, "\\Foobar" ); + status = pNtCreateKey( &subkey, am, &attr, 0, 0, 0, 0 ); + todo_wine + ok( status == STATUS_OBJECT_NAME_NOT_FOUND, "NtCreateKey failed: 0x%08x\n", status ); + pRtlFreeUnicodeString( &str ); + + pRtlCreateUnicodeStringFromAsciiz( &str, "\\Foobar\\Machine" ); + status = pNtCreateKey( &subkey, am, &attr, 0, 0, 0, 0 ); + todo_wine + ok( status == STATUS_OBJECT_PATH_NOT_FOUND, "NtCreateKey failed: 0x%08x\n", status ); + pRtlFreeUnicodeString( &str ); + + pRtlCreateUnicodeStringFromAsciiz( &str, "\\Machine\\Software\\Classes" ); + status = pNtCreateKey( &subkey, am, &attr, 0, 0, 0, 0 ); + todo_wine + ok( status == STATUS_OBJECT_PATH_NOT_FOUND, "NtCreateKey failed: 0x%08x\n", status ); + pRtlFreeUnicodeString( &str ); + + pRtlCreateUnicodeStringFromAsciiz( &str, "Machine\\Software\\Classes" ); + status = pNtCreateKey( &subkey, am, &attr, 0, 0, 0, 0 ); + todo_wine + ok( status == STATUS_OBJECT_PATH_SYNTAX_BAD, "NtCreateKey failed: 0x%08x\n", status ); + pRtlFreeUnicodeString( &str ); + + pRtlCreateUnicodeStringFromAsciiz( &str, "\\Device\\Null" ); + status = pNtCreateKey( &subkey, am, &attr, 0, 0, 0, 0 ); + todo_wine + ok( status == STATUS_OBJECT_TYPE_MISMATCH, "NtCreateKey failed: 0x%08x\n", status ); + pRtlFreeUnicodeString( &str ); + + pRtlCreateUnicodeStringFromAsciiz( &str, "\\Registry\\Machine\\Software\\Classes" ); + status = pNtCreateKey( &subkey, am, &attr, 0, 0, 0, 0 ); + ok( status == STATUS_SUCCESS || status == STATUS_ACCESS_DENIED, + "NtCreateKey failed: 0x%08x\n", status ); + if (!status) pNtClose( subkey ); + pRtlFreeUnicodeString( &str ); + + /* the REGISTRY part is case-sensitive unless OBJ_CASE_INSENSITIVE is specified */ + attr.Attributes = 0; + pRtlCreateUnicodeStringFromAsciiz( &str, "\\Registry\\Machine\\Software\\Classes" ); + status = pNtCreateKey( &subkey, am, &attr, 0, 0, 0, 0 ); + todo_wine + ok( status == STATUS_OBJECT_PATH_NOT_FOUND, "NtCreateKey failed: 0x%08x\n", status ); + pRtlFreeUnicodeString( &str ); + + pRtlCreateUnicodeStringFromAsciiz( &str, "\\REGISTRY\\Machine\\Software\\Classes" ); + status = pNtCreateKey( &subkey, am, &attr, 0, 0, 0, 0 ); + ok( status == STATUS_SUCCESS || status == STATUS_ACCESS_DENIED, + "NtCreateKey failed: 0x%08x\n", status ); + if (!status) pNtClose( subkey ); + pRtlFreeUnicodeString( &str ); + + pRtlCreateUnicodeStringFromAsciiz( &str, "\\REGISTRY\\MACHINE\\SOFTWARE\\CLASSES" ); + status = pNtCreateKey( &subkey, am, &attr, 0, 0, 0, 0 ); + ok( status == STATUS_SUCCESS || status == STATUS_ACCESS_DENIED, + "NtCreateKey failed: 0x%08x\n", status ); + if (!status) pNtClose( subkey ); + pRtlFreeUnicodeString( &str ); + pNtClose(key); } @@ -639,7 +802,7 @@ ok(status == STATUS_SUCCESS, "NtSetValueKey Failed: 0x%08x\n", status); status = pNtQueryValueKey(key, &ValName, KeyValuePartialInformation, &pi, sizeof(pi), &len); - ok(status == STATUS_SUCCESS, "NtQueryValueKey should have returned STATUS_BUFFER_TOO_SMALL instead of 0x%08x\n", status); + ok(status == STATUS_SUCCESS, "NtQueryValueKey should have returned STATUS_SUCCESS instead of 0x%08x\n", status); ok(pi.Type == 0xff00ff00, "Type=%x\n", pi.Type); ok(pi.DataLength == 0, "DataLength=%u\n", pi.DataLength); pRtlFreeUnicodeString(&ValName); Index: modules/rostests/winetests/ntdll/rtl.c =================================================================== --- modules/rostests/winetests/ntdll/rtl.c (revision 70979) +++ modules/rostests/winetests/ntdll/rtl.c (working copy) @@ -26,6 +26,9 @@ #include "ntdll_test.h" #include "inaddr.h" #include "in6addr.h" +#include "initguid.h" +#define COBJMACROS +#include "shobjidl.h" #ifndef __WINE_WINTERNL_H @@ -110,6 +113,8 @@ static NTSTATUS (WINAPI *pRtlCompressBuffer)(USHORT, const UCHAR*, ULONG, PUCHAR, ULONG, ULONG, PULONG, PVOID); static BOOL (WINAPI *pRtlIsCriticalSectionLocked)(CRITICAL_SECTION *); static BOOL (WINAPI *pRtlIsCriticalSectionLockedByThread)(CRITICAL_SECTION *); +static NTSTATUS (WINAPI *pRtlInitializeCriticalSectionEx)(CRITICAL_SECTION *, ULONG, ULONG); +static NTSTATUS (WINAPI *pRtlQueryPackageIdentity)(HANDLE, WCHAR*, SIZE_T*, WCHAR*, SIZE_T*, BOOLEAN*); static HMODULE hkernel32 = 0; static BOOL (WINAPI *pIsWow64Process)(HANDLE, PBOOL); @@ -174,6 +179,8 @@ pRtlCompressBuffer = (void *)GetProcAddress(hntdll, "RtlCompressBuffer"); pRtlIsCriticalSectionLocked = (void *)GetProcAddress(hntdll, "RtlIsCriticalSectionLocked"); pRtlIsCriticalSectionLockedByThread = (void *)GetProcAddress(hntdll, "RtlIsCriticalSectionLockedByThread"); + pRtlInitializeCriticalSectionEx = (void *)GetProcAddress(hntdll, "RtlInitializeCriticalSectionEx"); + pRtlQueryPackageIdentity = (void *)GetProcAddress(hntdll, "RtlQueryPackageIdentity"); } hkernel32 = LoadLibraryA("kernel32.dll"); ok(hkernel32 != 0, "LoadLibrary failed\n"); @@ -3165,6 +3172,109 @@ DeleteCriticalSection(&info.crit); } +static void test_RtlInitializeCriticalSectionEx(void) +{ + static const CRITICAL_SECTION_DEBUG *no_debug = (void *)~(ULONG_PTR)0; + CRITICAL_SECTION cs; + + if (!pRtlInitializeCriticalSectionEx) + { + win_skip("RtlInitializeCriticalSectionEx is not available\n"); + return; + } + + memset(&cs, 0x11, sizeof(cs)); + pRtlInitializeCriticalSectionEx(&cs, 0, 0); + ok((cs.DebugInfo != NULL && cs.DebugInfo != no_debug) || broken(cs.DebugInfo == no_debug) /* >= Win 8 */, + "expected DebugInfo != NULL and DebugInfo != ~0, got %p\n", cs.DebugInfo); + ok(cs.LockCount == -1, "expected LockCount == -1, got %d\n", cs.LockCount); + ok(cs.RecursionCount == 0, "expected RecursionCount == 0, got %d\n", cs.RecursionCount); + ok(cs.LockSemaphore == 0, "expected LockSemaphore == 0, got %p\n", cs.LockSemaphore); + ok(cs.SpinCount == 0, "expected SpinCount == 0, got %ld\n", cs.SpinCount); + RtlDeleteCriticalSection((RTL_CRITICAL_SECTION *)&cs); + + memset(&cs, 0x11, sizeof(cs)); + pRtlInitializeCriticalSectionEx(&cs, 0, RTL_CRITICAL_SECTION_FLAG_NO_DEBUG_INFO); + todo_wine + ok(cs.DebugInfo == no_debug, "expected DebugInfo == ~0, got %p\n", cs.DebugInfo); + ok(cs.LockCount == -1, "expected LockCount == -1, got %d\n", cs.LockCount); + ok(cs.RecursionCount == 0, "expected RecursionCount == 0, got %d\n", cs.RecursionCount); + ok(cs.LockSemaphore == 0, "expected LockSemaphore == 0, got %p\n", cs.LockSemaphore); + ok(cs.SpinCount == 0 || broken(cs.SpinCount != 0) /* >= Win 8 */, + "expected SpinCount == 0, got %ld\n", cs.SpinCount); + RtlDeleteCriticalSection((RTL_CRITICAL_SECTION *)&cs); +} + +static void test_RtlQueryPackageIdentity(void) +{ + const WCHAR programW[] = {'M','i','c','r','o','s','o','f','t','.','W','i','n','d','o','w','s','.', + 'P','h','o','t','o','s','_','8','w','e','k','y','b','3','d','8','b','b','w','e','!','A','p','p',0}; + const WCHAR fullnameW[] = {'M','i','c','r','o','s','o','f','t','.','W','i','n','d','o','w','s','.', + 'P','h','o','t','o','s', 0}; + const WCHAR appidW[] = {'A','p','p',0}; + IApplicationActivationManager *manager; + WCHAR buf1[MAX_PATH], buf2[MAX_PATH]; + HANDLE process, token; + SIZE_T size1, size2; + NTSTATUS status; + DWORD processid; + HRESULT hr; + BOOL ret; + + if (!pRtlQueryPackageIdentity) + { + win_skip("RtlQueryPackageIdentity not available\n"); + return; + } + + size1 = size2 = MAX_PATH * sizeof(WCHAR); + status = pRtlQueryPackageIdentity((HANDLE)~(ULONG_PTR)3, buf1, &size1, buf2, &size2, NULL); + ok(status == STATUS_NOT_FOUND, "expected STATUS_NOT_FOUND, got %08x\n", status); + + CoInitializeEx(0, COINIT_APARTMENTTHREADED); + hr = CoCreateInstance(&CLSID_ApplicationActivationManager, NULL, CLSCTX_LOCAL_SERVER, + &IID_IApplicationActivationManager, (void **)&manager); + if (FAILED(hr)) + { + todo_wine win_skip("Failed to create ApplicationActivationManager (%x)\n", hr); + goto done; + } + + hr = IApplicationActivationManager_ActivateApplication(manager, programW, NULL, + AO_NOERRORUI, &processid); + if (FAILED(hr)) + { + todo_wine win_skip("Failed to start program (%x)\n", hr); + IApplicationActivationManager_Release(manager); + goto done; + } + + process = OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION | PROCESS_TERMINATE, FALSE, processid); + ok(process != NULL, "OpenProcess failed with %u\n", GetLastError()); + ret = OpenProcessToken(process, TOKEN_QUERY, &token); + ok(ret, "OpenProcessToken failed with error %u\n", GetLastError()); + + size1 = size2 = MAX_PATH * sizeof(WCHAR); + status = pRtlQueryPackageIdentity(token, buf1, &size1, buf2, &size2, NULL); + ok(status == STATUS_SUCCESS, "Expected STATUS_SUCCESS, got %08x\n", status); + + ok(!memcmp(buf1, fullnameW, sizeof(fullnameW) - sizeof(WCHAR)), + "Expected buf1 to begin with %s, got %s\n", wine_dbgstr_w(fullnameW), wine_dbgstr_w(buf1)); + ok(size1 >= sizeof(WCHAR) && !(size1 % sizeof(WCHAR)), "Unexpected size1 = %lu\n", size1); + ok(buf1[size1 / sizeof(WCHAR) - 1] == 0, "Expected buf1[%lu] == 0\n", size1 / sizeof(WCHAR) - 1); + + ok(!lstrcmpW(buf2, appidW), "Expected buf2 to be %s, got %s\n", wine_dbgstr_w(appidW), wine_dbgstr_w(buf2)); + ok(size2 >= sizeof(WCHAR) && !(size2 % sizeof(WCHAR)), "Unexpected size2 = %lu\n", size2); + ok(buf2[size2 / sizeof(WCHAR) - 1] == 0, "Expected buf2[%lu] == 0\n", size2 / sizeof(WCHAR) - 1); + + CloseHandle(token); + TerminateProcess(process, 0); + CloseHandle(process); + +done: + CoUninitialize(); +} + START_TEST(rtl) { InitFunctionPtrs(); @@ -3206,4 +3316,6 @@ test_RtlGetCompressionWorkSpaceSize(); test_RtlDecompressBuffer(); test_RtlIsCriticalSectionLocked(); + test_RtlInitializeCriticalSectionEx(); + test_RtlQueryPackageIdentity(); }