Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=53781
The Matrix Awakens MegaCity Unreal Engine 5.1 demo and Hogwarts Legacy call this.
Duplicate Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=54513
-- v3: cfgmgr32/tests: Add CM_MapCrToWin32Err tests.
From: Mohamad Al-Jaf mohamadaljaf@gmail.com
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=53781 --- dlls/cfgmgr32/Makefile.in | 3 ++ dlls/cfgmgr32/cfgmgr32.spec | 1 + dlls/cfgmgr32/main.c | 58 +++++++++++++++++++++++++++++++++++++ include/cfgmgr32.h | 1 + 4 files changed, 63 insertions(+) create mode 100644 dlls/cfgmgr32/main.c
diff --git a/dlls/cfgmgr32/Makefile.in b/dlls/cfgmgr32/Makefile.in index 10621fa5dc7..f05b3176aa3 100644 --- a/dlls/cfgmgr32/Makefile.in +++ b/dlls/cfgmgr32/Makefile.in @@ -1,3 +1,6 @@ MODULE = cfgmgr32.dll IMPORTLIB = cfgmgr32 IMPORTS = setupapi + +C_SRCS = \ + main.c diff --git a/dlls/cfgmgr32/cfgmgr32.spec b/dlls/cfgmgr32/cfgmgr32.spec index 69ec784de68..3b4f6106618 100644 --- a/dlls/cfgmgr32/cfgmgr32.spec +++ b/dlls/cfgmgr32/cfgmgr32.spec @@ -126,6 +126,7 @@ @ stdcall CM_Locate_DevNodeW(ptr wstr long) setupapi.CM_Locate_DevNodeW @ stdcall CM_Locate_DevNode_ExA(ptr str long long) setupapi.CM_Locate_DevNode_ExA @ stdcall CM_Locate_DevNode_ExW(ptr wstr long long) setupapi.CM_Locate_DevNode_ExW +@ stdcall CM_MapCrToWin32Err(long long) @ stub CM_Merge_Range_List @ stub CM_Modify_Res_Des @ stub CM_Modify_Res_Des_Ex diff --git a/dlls/cfgmgr32/main.c b/dlls/cfgmgr32/main.c new file mode 100644 index 00000000000..f0907bbc9bd --- /dev/null +++ b/dlls/cfgmgr32/main.c @@ -0,0 +1,58 @@ +/* + * Copyright (C) 2023 Mohamad Al-Jaf + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include "wine/debug.h" +#include "cfgmgr32.h" + +WINE_DEFAULT_DEBUG_CHANNEL(cfgmgr32); + +/*********************************************************************** + * CM_MapCrToWin32Err (cfgmgr32.@) + */ +CMAPI DWORD WINAPI CM_MapCrToWin32Err( CONFIGRET code, DWORD default_error ) +{ + TRACE( "code: %ld, default_error: %ld\n", code, default_error ); + + switch (code) + { + case CR_SUCCESS: return ERROR_SUCCESS; + case CR_OUT_OF_MEMORY: return ERROR_NOT_ENOUGH_MEMORY; + case CR_INVALID_POINTER: return ERROR_INVALID_USER_BUFFER; + case CR_INVALID_FLAG: return ERROR_INVALID_FLAGS; + case CR_INVALID_DEVNODE: + case CR_INVALID_DEVICE_ID: + case CR_INVALID_MACHINENAME: + case CR_INVALID_PROPERTY: + case CR_INVALID_REFERENCE_STRING: return ERROR_INVALID_DATA; + case CR_NO_SUCH_DEVNODE: + case CR_NO_SUCH_VALUE: + case CR_NO_SUCH_DEVICE_INTERFACE: return ERROR_NOT_FOUND; + case CR_ALREADY_SUCH_DEVNODE: return ERROR_ALREADY_EXISTS; + case CR_BUFFER_SMALL: return ERROR_INSUFFICIENT_BUFFER; + case CR_NO_REGISTRY_HANDLE: return ERROR_INVALID_HANDLE; + case CR_REGISTRY_ERROR: return ERROR_REGISTRY_CORRUPT; + case CR_NO_SUCH_REGISTRY_KEY: return ERROR_FILE_NOT_FOUND; + case CR_REMOTE_COMM_FAILURE: + case CR_MACHINE_UNAVAILABLE: + case CR_NO_CM_SERVICES: return ERROR_SERVICE_NOT_ACTIVE; + case CR_ACCESS_DENIED: return ERROR_ACCESS_DENIED; + case CR_CALL_NOT_IMPLEMENTED: return ERROR_CALL_NOT_IMPLEMENTED; + } + + return default_error; +} diff --git a/include/cfgmgr32.h b/include/cfgmgr32.h index d300c4babaa..b78f118622e 100644 --- a/include/cfgmgr32.h +++ b/include/cfgmgr32.h @@ -242,6 +242,7 @@ CMAPI WORD WINAPI CM_Get_Version(void); CMAPI CONFIGRET WINAPI CM_Locate_DevNodeA(PDEVINST,DEVINSTID_A,ULONG); CMAPI CONFIGRET WINAPI CM_Locate_DevNodeW(PDEVINST,DEVINSTID_W,ULONG); #define CM_Locate_DevNode WINELIB_NAME_AW(CM_Locate_DevNode) +CMAPI DWORD WINAPI CM_MapCrToWin32Err(CONFIGRET,DWORD); CMAPI CONFIGRET WINAPI CM_Open_DevNode_Key(DEVINST dnDevInst, REGSAM access, ULONG ulHardwareProfile, REGDISPOSITION disposition, PHKEY phkDevice, ULONG ulFlags); CMAPI CONFIGRET WINAPI CM_Request_Device_EjectA(DEVINST dev, PPNP_VETO_TYPE type, LPSTR name, ULONG length, ULONG flags);
From: Mohamad Al-Jaf mohamadaljaf@gmail.com
--- configure.ac | 1 + dlls/cfgmgr32/tests/Makefile.in | 5 ++ dlls/cfgmgr32/tests/cfgmgr32.c | 125 ++++++++++++++++++++++++++++++++ 3 files changed, 131 insertions(+) create mode 100644 dlls/cfgmgr32/tests/Makefile.in create mode 100644 dlls/cfgmgr32/tests/cfgmgr32.c
diff --git a/configure.ac b/configure.ac index 84fadd08853..f01b975e916 100644 --- a/configure.ac +++ b/configure.ac @@ -2382,6 +2382,7 @@ WINE_CONFIG_MAKEFILE(dlls/capi2032) WINE_CONFIG_MAKEFILE(dlls/cards) WINE_CONFIG_MAKEFILE(dlls/cdosys) WINE_CONFIG_MAKEFILE(dlls/cfgmgr32) +WINE_CONFIG_MAKEFILE(dlls/cfgmgr32/tests) WINE_CONFIG_MAKEFILE(dlls/clusapi) WINE_CONFIG_MAKEFILE(dlls/cng.sys) WINE_CONFIG_MAKEFILE(dlls/combase) diff --git a/dlls/cfgmgr32/tests/Makefile.in b/dlls/cfgmgr32/tests/Makefile.in new file mode 100644 index 00000000000..4e1f97b1c0c --- /dev/null +++ b/dlls/cfgmgr32/tests/Makefile.in @@ -0,0 +1,5 @@ +TESTDLL = cfgmgr32.dll +IMPORTS = cfgmgr32 + +C_SRCS = \ + cfgmgr32.c diff --git a/dlls/cfgmgr32/tests/cfgmgr32.c b/dlls/cfgmgr32/tests/cfgmgr32.c new file mode 100644 index 00000000000..3eb59301e48 --- /dev/null +++ b/dlls/cfgmgr32/tests/cfgmgr32.c @@ -0,0 +1,125 @@ +/* + * Copyright (C) 2023 Mohamad Al-Jaf + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include "wine/test.h" +#include "cfgmgr32.h" + +#define DEFAULT_ERROR 0xdeadbeef + +static void test_CM_MapCrToWin32Err(void) +{ + DWORD ret, expected; + unsigned int i; + + static const struct + { + CONFIGRET code; + DWORD win32_error; + } + map_codes[] = + { + { CR_SUCCESS, ERROR_SUCCESS }, + { CR_OUT_OF_MEMORY, ERROR_NOT_ENOUGH_MEMORY }, + { CR_INVALID_POINTER, ERROR_INVALID_USER_BUFFER }, + { CR_INVALID_FLAG, ERROR_INVALID_FLAGS }, + { CR_INVALID_DEVNODE, ERROR_INVALID_DATA }, + { CR_INVALID_DEVINST, ERROR_INVALID_DATA }, + { CR_NO_SUCH_DEVNODE, ERROR_NOT_FOUND }, + { CR_NO_SUCH_DEVINST, ERROR_NOT_FOUND }, + { CR_ALREADY_SUCH_DEVNODE, ERROR_ALREADY_EXISTS }, + { CR_ALREADY_SUCH_DEVINST, ERROR_ALREADY_EXISTS }, + { CR_BUFFER_SMALL, ERROR_INSUFFICIENT_BUFFER }, + { CR_NO_REGISTRY_HANDLE, ERROR_INVALID_HANDLE }, + { CR_REGISTRY_ERROR, ERROR_REGISTRY_CORRUPT }, + { CR_INVALID_DEVICE_ID, ERROR_INVALID_DATA }, + { CR_NO_SUCH_VALUE, ERROR_NOT_FOUND }, + { CR_NO_SUCH_REGISTRY_KEY, ERROR_FILE_NOT_FOUND }, + { CR_INVALID_MACHINENAME, ERROR_INVALID_DATA }, + { CR_REMOTE_COMM_FAILURE, ERROR_SERVICE_NOT_ACTIVE }, + { CR_MACHINE_UNAVAILABLE, ERROR_SERVICE_NOT_ACTIVE }, + { CR_NO_CM_SERVICES, ERROR_SERVICE_NOT_ACTIVE }, + { CR_ACCESS_DENIED, ERROR_ACCESS_DENIED }, + { CR_CALL_NOT_IMPLEMENTED, ERROR_CALL_NOT_IMPLEMENTED }, + { CR_INVALID_PROPERTY, ERROR_INVALID_DATA }, + { CR_NO_SUCH_DEVICE_INTERFACE, ERROR_NOT_FOUND }, + { CR_INVALID_REFERENCE_STRING, ERROR_INVALID_DATA }, + { CR_DEFAULT, DEFAULT_ERROR }, + { CR_INVALID_RES_DES, DEFAULT_ERROR }, + { CR_INVALID_LOG_CONF, DEFAULT_ERROR }, + { CR_INVALID_ARBITRATOR, DEFAULT_ERROR }, + { CR_INVALID_NODELIST, DEFAULT_ERROR }, + { CR_DEVNODE_HAS_REQS, DEFAULT_ERROR }, + { CR_DEVINST_HAS_REQS, DEFAULT_ERROR }, + { CR_INVALID_RESOURCEID, DEFAULT_ERROR }, + { CR_DLVXD_NOT_FOUND, DEFAULT_ERROR }, + { CR_NO_MORE_LOG_CONF, DEFAULT_ERROR }, + { CR_NO_MORE_RES_DES, DEFAULT_ERROR }, + { CR_INVALID_RANGE_LIST, DEFAULT_ERROR }, + { CR_INVALID_RANGE, DEFAULT_ERROR }, + { CR_FAILURE, DEFAULT_ERROR }, + { CR_NO_SUCH_LOGICAL_DEV, DEFAULT_ERROR }, + { CR_CREATE_BLOCKED, DEFAULT_ERROR }, + { CR_NOT_SYSTEM_VM, DEFAULT_ERROR }, + { CR_REMOVE_VETOED, DEFAULT_ERROR }, + { CR_APM_VETOED, DEFAULT_ERROR }, + { CR_INVALID_LOAD_TYPE, DEFAULT_ERROR }, + { CR_NO_ARBITRATOR, DEFAULT_ERROR }, + { CR_INVALID_DATA, DEFAULT_ERROR }, + { CR_INVALID_API, DEFAULT_ERROR }, + { CR_DEVLOADER_NOT_READY, DEFAULT_ERROR }, + { CR_NEED_RESTART, DEFAULT_ERROR }, + { CR_NO_MORE_HW_PROFILES, DEFAULT_ERROR }, + { CR_DEVICE_NOT_THERE, DEFAULT_ERROR }, + { CR_WRONG_TYPE, DEFAULT_ERROR }, + { CR_INVALID_PRIORITY, DEFAULT_ERROR }, + { CR_NOT_DISABLEABLE, DEFAULT_ERROR }, + { CR_FREE_RESOURCES, DEFAULT_ERROR }, + { CR_QUERY_VETOED, DEFAULT_ERROR }, + { CR_CANT_SHARE_IRQ, DEFAULT_ERROR }, + { CR_NO_DEPENDENT, DEFAULT_ERROR }, + { CR_SAME_RESOURCES, DEFAULT_ERROR }, + { CR_DEVICE_INTERFACE_ACTIVE, DEFAULT_ERROR }, + { CR_INVALID_CONFLICT_LIST, DEFAULT_ERROR }, + { CR_INVALID_INDEX, DEFAULT_ERROR }, + { CR_INVALID_STRUCTURE_SIZE, DEFAULT_ERROR }, + { NUM_CR_RESULTS, DEFAULT_ERROR }, + }; + + SetLastError(0xdeadbeef); + ret = 0; + ret = CM_MapCrToWin32Err( 0xdeadbeef, DEFAULT_ERROR ); + ok( ret == DEFAULT_ERROR, "expected default error, got %ld.\n", ret ); + ok( GetLastError() == 0xdeadbeef, "unexpected error %ld.\n", GetLastError() ); + + for ( i = 0; i < sizeof(map_codes) / sizeof(map_codes[0]); i++ ) + { + ret = 0xdeadbeef; + ret = CM_MapCrToWin32Err( map_codes[i].code, DEFAULT_ERROR ); + expected = map_codes[i].win32_error; + + if (expected == DEFAULT_ERROR) + ok( ret == DEFAULT_ERROR, "expected default error, got %ld.\n", ret ); + else + ok( ret == expected, "expected %ld, got %ld.\n", expected, ret ); + } +} + +START_TEST(cfgmgr32) +{ + test_CM_MapCrToWin32Err(); +}
On Tue Feb 21 04:54:56 2023 +0000, **** wrote:
Marvin replied on the mailing list:
Hi, It looks like your patch introduced the new failures shown below. Please investigate and fix them before resubmitting your patch. If they are not new, fixing them anyway would help a lot. Otherwise please ask for the known failures list to be updated. The tests also ran into some preexisting test failures. If you know how to fix them that would be helpful. See the TestBot job for the details: The full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=129771 Your paranoid android. === build (build log) === ../wine/dlls/cfgmgr32/tests/cfgmgr32.c:60:40: error: initializer element is not constant ../wine/dlls/cfgmgr32/tests/cfgmgr32.c:61:40: error: initializer element is not constant ../wine/dlls/cfgmgr32/tests/cfgmgr32.c:62:40: error: initializer element is not constant ../wine/dlls/cfgmgr32/tests/cfgmgr32.c:63:40: error: initializer element is not constant ../wine/dlls/cfgmgr32/tests/cfgmgr32.c:64:40: error: initializer element is not constant ../wine/dlls/cfgmgr32/tests/cfgmgr32.c:65:40: error: initializer element is not constant ../wine/dlls/cfgmgr32/tests/cfgmgr32.c:66:40: error: initializer element is not constant ../wine/dlls/cfgmgr32/tests/cfgmgr32.c:67:40: error: initializer element is not constant ../wine/dlls/cfgmgr32/tests/cfgmgr32.c:68:40: error: initializer element is not constant ../wine/dlls/cfgmgr32/tests/cfgmgr32.c:69:40: error: initializer element is not constant ../wine/dlls/cfgmgr32/tests/cfgmgr32.c:70:40: error: initializer element is not constant ../wine/dlls/cfgmgr32/tests/cfgmgr32.c:71:40: error: initializer element is not constant ../wine/dlls/cfgmgr32/tests/cfgmgr32.c:72:40: error: initializer element is not constant ../wine/dlls/cfgmgr32/tests/cfgmgr32.c:73:40: error: initializer element is not constant ../wine/dlls/cfgmgr32/tests/cfgmgr32.c:74:40: error: initializer element is not constant ../wine/dlls/cfgmgr32/tests/cfgmgr32.c:75:40: error: initializer element is not constant ../wine/dlls/cfgmgr32/tests/cfgmgr32.c:76:40: error: initializer element is not constant ../wine/dlls/cfgmgr32/tests/cfgmgr32.c:77:40: error: initializer element is not constant ../wine/dlls/cfgmgr32/tests/cfgmgr32.c:78:40: error: initializer element is not constant ../wine/dlls/cfgmgr32/tests/cfgmgr32.c:79:40: error: initializer element is not constant ../wine/dlls/cfgmgr32/tests/cfgmgr32.c:80:40: error: initializer element is not constant ../wine/dlls/cfgmgr32/tests/cfgmgr32.c:81:40: error: initializer element is not constant ../wine/dlls/cfgmgr32/tests/cfgmgr32.c:82:40: error: initializer element is not constant ../wine/dlls/cfgmgr32/tests/cfgmgr32.c:83:40: error: initializer element is not constant ../wine/dlls/cfgmgr32/tests/cfgmgr32.c:84:40: error: initializer element is not constant ../wine/dlls/cfgmgr32/tests/cfgmgr32.c:85:40: error: initializer element is not constant ../wine/dlls/cfgmgr32/tests/cfgmgr32.c:86:40: error: initializer element is not constant ../wine/dlls/cfgmgr32/tests/cfgmgr32.c:87:40: error: initializer element is not constant ../wine/dlls/cfgmgr32/tests/cfgmgr32.c:88:40: error: initializer element is not constant ../wine/dlls/cfgmgr32/tests/cfgmgr32.c:89:40: error: initializer element is not constant ../wine/dlls/cfgmgr32/tests/cfgmgr32.c:90:40: error: initializer element is not constant ../wine/dlls/cfgmgr32/tests/cfgmgr32.c:91:40: error: initializer element is not constant ../wine/dlls/cfgmgr32/tests/cfgmgr32.c:92:40: error: initializer element is not constant ../wine/dlls/cfgmgr32/tests/cfgmgr32.c:93:40: error: initializer element is not constant ../wine/dlls/cfgmgr32/tests/cfgmgr32.c:94:40: error: initializer element is not constant ../wine/dlls/cfgmgr32/tests/cfgmgr32.c:95:40: error: initializer element is not constant ../wine/dlls/cfgmgr32/tests/cfgmgr32.c:96:40: error: initializer element is not constant ../wine/dlls/cfgmgr32/tests/cfgmgr32.c:97:40: error: initializer element is not constant ../wine/dlls/cfgmgr32/tests/cfgmgr32.c:98:40: error: initializer element is not constant ../wine/dlls/cfgmgr32/tests/cfgmgr32.c:99:40: error: initializer element is not constant Makefile:9020: recipe for target 'dlls/cfgmgr32/tests/i386-windows/cfgmgr32.o' failed Task: The exe32 Wine build failed
This built fine on my PC as well as on `debian11` and `debian11b`.
v3 - Define DEFAULT_ERROR rather than using a const.
Zebediah Figura (@zfigura) commented about dlls/cfgmgr32/tests/cfgmgr32.c:
{ CR_QUERY_VETOED, DEFAULT_ERROR },
{ CR_CANT_SHARE_IRQ, DEFAULT_ERROR },
{ CR_NO_DEPENDENT, DEFAULT_ERROR },
{ CR_SAME_RESOURCES, DEFAULT_ERROR },
{ CR_DEVICE_INTERFACE_ACTIVE, DEFAULT_ERROR },
{ CR_INVALID_CONFLICT_LIST, DEFAULT_ERROR },
{ CR_INVALID_INDEX, DEFAULT_ERROR },
{ CR_INVALID_STRUCTURE_SIZE, DEFAULT_ERROR },
{ NUM_CR_RESULTS, DEFAULT_ERROR },
- };
- SetLastError(0xdeadbeef);
- ret = 0;
- ret = CM_MapCrToWin32Err( 0xdeadbeef, DEFAULT_ERROR );
- ok( ret == DEFAULT_ERROR, "expected default error, got %ld.\n", ret );
- ok( GetLastError() == 0xdeadbeef, "unexpected error %ld.\n", GetLastError() );
The fact that DEFAULT_ERROR is 0xdeadbeef makes the GetLastError() test less interesting.
The fact that DEFAULT_ERROR is a macro makes this above observation less obvious, which is one reason I would just write it out everywhere.
(Also, there's a dead assignment to "ret" in here.)
Zebediah Figura (@zfigura) commented about dlls/cfgmgr32/tests/cfgmgr32.c:
- SetLastError(0xdeadbeef);
- ret = 0;
- ret = CM_MapCrToWin32Err( 0xdeadbeef, DEFAULT_ERROR );
- ok( ret == DEFAULT_ERROR, "expected default error, got %ld.\n", ret );
- ok( GetLastError() == 0xdeadbeef, "unexpected error %ld.\n", GetLastError() );
- for ( i = 0; i < sizeof(map_codes) / sizeof(map_codes[0]); i++ )
- {
ret = 0xdeadbeef;
ret = CM_MapCrToWin32Err( map_codes[i].code, DEFAULT_ERROR );
expected = map_codes[i].win32_error;
if (expected == DEFAULT_ERROR)
ok( ret == DEFAULT_ERROR, "expected default error, got %ld.\n", ret );
else
ok( ret == expected, "expected %ld, got %ld.\n", expected, ret );
This seems excessive; I'd just make it a single ok() statement. For that matter, I wouldn't bother with an "expected" variable.
On Tue Feb 21 05:22:44 2023 +0000, Zebediah Figura wrote:
The fact that DEFAULT_ERROR is 0xdeadbeef makes the GetLastError() test less interesting. The fact that DEFAULT_ERROR is a macro makes this above observation less obvious, which is one reason I would just write it out everywhere. (Also, there's a dead assignment to "ret" in here.)
It's to show that the function doesn't call `SetLastError`, but it's not really needed so I'll remove that block.
So get rid of the DEFAULT_ERROR macro and replace all instances with `0xdeadbeef`? I always thought it was good practice to define variables that are used repeatedly. Though, it doesn't really make a difference in this case, win32_error can be anything for the unsupported codes.
But IMO it looks clearer with DEFAULT_ERROR. It doesn't really matter to me so it's up to you.
On Tue Feb 21 05:23:38 2023 +0000, Zebediah Figura wrote:
This seems excessive; I'd just make it a single ok() statement. For that matter, I wouldn't bother with an "expected" variable.
Sure, 0xdeadbeef is clear that it's a default error so the first ok statement isn't needed.