From 1c79a6a2d08329f69db5dedced5362973afbafdc Mon Sep 17 00:00:00 2001 From: Andrew Eikum Date: Mon, 29 Oct 2018 09:28:28 -0500 Subject: [PATCH] lsteamclient: Rework cb struct generation --- lsteamclient/cb_getapi_table.dat | 3 + lsteamclient/gen_wrapper.py | 99 +++++++++++++------------- lsteamclient/struct_converters.dat | 3 + lsteamclient/struct_converters.h | 43 +++++++++++ lsteamclient/struct_converters_128.cpp | 18 +++++ 5 files changed, 117 insertions(+), 49 deletions(-) diff --git a/lsteamclient/cb_getapi_table.dat b/lsteamclient/cb_getapi_table.dat index 76791d1b..63a4ba7f 100644 --- a/lsteamclient/cb_getapi_table.dat +++ b/lsteamclient/cb_getapi_table.dat @@ -635,6 +635,7 @@ case 1318: default: case sizeof(struct winRemoteStorageGetPublishedFileDetailsResult_t_9748): cb_RemoteStorageGetPublishedFileDetailsResult_t_9748(lin_callback, callback); break; case sizeof(struct winRemoteStorageGetPublishedFileDetailsResult_t_9744): cb_RemoteStorageGetPublishedFileDetailsResult_t_9744(lin_callback, callback); break; + case sizeof(struct winRemoteStorageGetPublishedFileDetailsResult_t_9740): cb_RemoteStorageGetPublishedFileDetailsResult_t_9740(lin_callback, callback); break; case sizeof(struct winRemoteStorageGetPublishedFileDetailsResult_t_9484): cb_RemoteStorageGetPublishedFileDetailsResult_t_9484(lin_callback, callback); break; } break; @@ -739,12 +740,14 @@ case 3401: switch(callback_len){ default: case sizeof(struct winSteamUGCQueryCompleted_t_24): cb_SteamUGCQueryCompleted_t_24(lin_callback, callback); break; + case sizeof(struct winSteamUGCQueryCompleted_t_20): cb_SteamUGCQueryCompleted_t_20(lin_callback, callback); break; } break; case 3402: switch(callback_len){ default: case sizeof(struct winSteamUGCRequestUGCDetailsResult_t_9768): cb_SteamUGCRequestUGCDetailsResult_t_9768(lin_callback, callback); break; + case sizeof(struct winSteamUGCRequestUGCDetailsResult_t_9764): cb_SteamUGCRequestUGCDetailsResult_t_9764(lin_callback, callback); break; case sizeof(struct winSteamUGCRequestUGCDetailsResult_t_9760): cb_SteamUGCRequestUGCDetailsResult_t_9760(lin_callback, callback); break; } break; diff --git a/lsteamclient/gen_wrapper.py b/lsteamclient/gen_wrapper.py index f4c860be..bb6dceed 100755 --- a/lsteamclient/gen_wrapper.py +++ b/lsteamclient/gen_wrapper.py @@ -389,27 +389,51 @@ cb_table = {} #layout. #TODO: could we optimize this by detecting if the structs are the #same layout at generation-time? -def handle_callback_struct(sdkver, callback, cb_num): - handler_name = "%s_%s" % (callback.displayname, callback.type.get_size()) +def handle_struct(sdkver, struct): + members = struct.get_children() + cb_num = None + for c in members: + if c.kind == clang.cindex.CursorKind.ENUM_DECL: + enums = c.get_children() + for e in enums: + if e.displayname == "k_iCallback": + cb_num = e.enum_value - if handler_name in generated_cb_handlers: - # we already have a handler for the callback struct of this size + if cb_num is None: + struct_name = "%s_%s" % (struct.displayname, sdkver) + handler_name = "struct_%s" % struct_name; return + else: + #for callbacks, we use the linux struct size in the cb dispatch switch + struct_name = "%s_%s" % (struct.displayname, struct.type.get_size()) + handler_name = "cb_%s" % struct_name; + if handler_name in generated_cb_handlers: + # we already have a handler for the callback struct of this size + return + if handler_name in skip_structs: + # due to padding, some structs have the same width across versions of + # the SDK. since we key our lin->win conversion on the win struct size, + # we can skip the smaller structs and just write into the padding on + # older versions + # TODO: we could automate this. see comment near skip_structs declaration + return - if handler_name in skip_structs: - # due to padding, some structs have the same width across versions of - # the SDK. since we key our lin->win conversion on the win struct size, - # we can skip the smaller structs and just write into the padding on - # older versions - # TODO: we could automate this. see comment near skip_structs declaration - return + cb_id = cb_num | (struct.type.get_size() << 16) + if cb_id in generated_cb_ids: + # either this cb changed name, or steam used the same ID for different structs + return - cb_id = cb_num | (callback.type.get_size() << 16) - if cb_id in generated_cb_ids: - # either this cb changed name, or steam used the same ID for different structs - return + generated_cb_ids.append(cb_id) - generated_cb_ids.append(cb_id) + datfile = open("struct_converters.dat", "a") + datfile.write("case 0x%08x: win_msg->m_cubParam = sizeof(struct win%s); win_msg->m_pubParam = HeapAlloc(GetProcessHeap(), 0, win_msg->m_cubParam); %s(lin_msg.m_pubParam, win_msg->m_pubParam); break;\n" % (cb_id, struct_name, handler_name)) + + generated_cb_handlers.append(handler_name) + + if not cb_num in cb_table.keys(): + # latest SDK linux size, list of windows struct names + cb_table[cb_num] = (struct.type.get_size(), []) + cb_table[cb_num][1].append(struct_name) filename_base = "struct_converters_%s" % sdkver cppname = "%s.cpp" % filename_base @@ -427,13 +451,10 @@ def handle_callback_struct(sdkver, callback, cb_num): cppfile.write("extern \"C\" {\n") cpp_files_need_close_brace.append(cppname) - datfile = open("struct_converters.dat", "a") - datfile.write("case 0x%08x: win_msg->m_cubParam = sizeof(struct win%s); win_msg->m_pubParam = HeapAlloc(GetProcessHeap(), 0, win_msg->m_cubParam); cb_%s(lin_msg.m_pubParam, win_msg->m_pubParam); break;\n" % (cb_id, handler_name, handler_name)) - hfile = open("struct_converters.h", "a") hfile.write("#pragma pack( push, 8 )\n") - hfile.write("struct win%s {\n" % handler_name) - for m in callback.get_children(): + hfile.write("struct win%s {\n" % struct_name) + for m in struct.get_children(): if m.kind == clang.cindex.CursorKind.FIELD_DECL: if m.type.kind == clang.cindex.TypeKind.CONSTANTARRAY: hfile.write(" %s %s[%u];\n" % (m.type.element_type.spelling, m.displayname, m.type.element_count)) @@ -441,11 +462,11 @@ def handle_callback_struct(sdkver, callback, cb_num): hfile.write(" %s %s;\n" % (m.type.spelling, m.displayname)) hfile.write("} __attribute__ ((ms_struct));\n") hfile.write("#pragma pack( pop )\n") - hfile.write("extern void cb_%s(void *l, void *w);\n\n" % handler_name) + hfile.write("extern void %s(void *l, void *w);\n\n" % handler_name) cppfile.write("#pragma pack( push, 8 )\n") - cppfile.write("struct win%s {\n" % handler_name) - for m in callback.get_children(): + cppfile.write("struct win%s {\n" % struct_name) + for m in struct.get_children(): if m.kind == clang.cindex.CursorKind.FIELD_DECL: if m.type.kind == clang.cindex.TypeKind.CONSTANTARRAY: cppfile.write(" %s %s[%u];\n" % (m.type.element_type.spelling, m.displayname, m.type.element_count)) @@ -454,10 +475,10 @@ def handle_callback_struct(sdkver, callback, cb_num): cppfile.write("} __attribute__ ((ms_struct));\n") cppfile.write("#pragma pack( pop )\n") - cppfile.write("void cb_%s(void *l, void *w)\n{\n" % handler_name) - cppfile.write(" %s *lin = (%s *)l;\n" % (callback.displayname, callback.displayname)) - cppfile.write(" struct win%s *win = (struct win%s *)w;\n" % (handler_name, handler_name)) - for m in callback.get_children(): + cppfile.write("void %s(void *l, void *w)\n{\n" % handler_name) + cppfile.write(" %s *lin = (%s *)l;\n" % (struct.displayname, struct.displayname)) + cppfile.write(" struct win%s *win = (struct win%s *)w;\n" % (struct_name, struct_name)) + for m in struct.get_children(): if m.kind == clang.cindex.CursorKind.FIELD_DECL: if m.type.kind == clang.cindex.TypeKind.CONSTANTARRAY: #TODO: if this is a struct, or packed differently, we'll have to @@ -467,26 +488,6 @@ def handle_callback_struct(sdkver, callback, cb_num): cppfile.write(" win->%s = lin->%s;\n" % (m.displayname, m.displayname)) cppfile.write("}\n\n") - generated_cb_handlers.append(handler_name) - - if not cb_num in cb_table.keys(): - # latest SDK linux size, list of windows struct names - cb_table[cb_num] = (callback.type.get_size(), []) - cb_table[cb_num][1].append(handler_name) - - -def handle_callback_maybe(sdkver, callback): - members = callback.get_children() - for c in members: - if c.kind == clang.cindex.CursorKind.ENUM_DECL: - enums = c.get_children() - for e in enums: - if e.displayname == "k_iCallback": - handle_callback_struct(sdkver, callback, e.enum_value) - - - - #clang.cindex.Config.set_library_file("/usr/lib/llvm-3.8/lib/libclang-3.8.so.1"); prog = re.compile("^#define\s*(\w*)\s*\"(.*)\"") @@ -521,7 +522,7 @@ for sdkver in sdk_versions: handle_class(sdkver, child) if child.kind == clang.cindex.CursorKind.STRUCT_DECL or \ child.kind == clang.cindex.CursorKind.CLASS_DECL: - handle_callback_maybe(sdkver, child) + handle_struct(sdkver, child) if child.displayname in print_sizes: sys.stdout.write("size of %s is %u\n" % (child.displayname, child.type.get_size())) diff --git a/lsteamclient/struct_converters.dat b/lsteamclient/struct_converters.dat index 6bfd3b94..6f2bbcc4 100644 --- a/lsteamclient/struct_converters.dat +++ b/lsteamclient/struct_converters.dat @@ -195,8 +195,10 @@ case 0x000411a6: win_msg->m_cubParam = sizeof(struct winHTML_ShowPopup_t_4); win case 0x000411a7: win_msg->m_cubParam = sizeof(struct winHTML_HidePopup_t_4); win_msg->m_pubParam = HeapAlloc(GetProcessHeap(), 0, win_msg->m_cubParam); cb_HTML_HidePopup_t_4(lin_msg.m_pubParam, win_msg->m_pubParam); break; case 0x001411a8: win_msg->m_cubParam = sizeof(struct winHTML_SizePopup_t_20); win_msg->m_pubParam = HeapAlloc(GetProcessHeap(), 0, win_msg->m_cubParam); cb_HTML_SizePopup_t_20(lin_msg.m_pubParam, win_msg->m_pubParam); break; case 0x001811a9: win_msg->m_cubParam = sizeof(struct winHTML_NewWindow_t_24); win_msg->m_pubParam = HeapAlloc(GetProcessHeap(), 0, win_msg->m_cubParam); cb_HTML_NewWindow_t_24(lin_msg.m_pubParam, win_msg->m_pubParam); break; +case 0x26240d4a: win_msg->m_cubParam = sizeof(struct winSteamUGCRequestUGCDetailsResult_t_9764); win_msg->m_pubParam = HeapAlloc(GetProcessHeap(), 0, win_msg->m_cubParam); cb_SteamUGCRequestUGCDetailsResult_t_9764(lin_msg.m_pubParam, win_msg->m_pubParam); break; case 0x001801f6: win_msg->m_cubParam = sizeof(struct winFavoritesListChanged_t_24); win_msg->m_pubParam = HeapAlloc(GetProcessHeap(), 0, win_msg->m_cubParam); cb_FavoritesListChanged_t_24(lin_msg.m_pubParam, win_msg->m_pubParam); break; case 0x000c051b: win_msg->m_cubParam = sizeof(struct winRemoteStorageFileShareResult_t_12); win_msg->m_pubParam = HeapAlloc(GetProcessHeap(), 0, win_msg->m_cubParam); cb_RemoteStorageFileShareResult_t_12(lin_msg.m_pubParam, win_msg->m_pubParam); break; +case 0x00140d49: win_msg->m_cubParam = sizeof(struct winSteamUGCQueryCompleted_t_20); win_msg->m_pubParam = HeapAlloc(GetProcessHeap(), 0, win_msg->m_cubParam); cb_SteamUGCQueryCompleted_t_20(lin_msg.m_pubParam, win_msg->m_pubParam); break; case 0x26200d4a: win_msg->m_cubParam = sizeof(struct winSteamUGCRequestUGCDetailsResult_t_9760); win_msg->m_pubParam = HeapAlloc(GetProcessHeap(), 0, win_msg->m_cubParam); cb_SteamUGCRequestUGCDetailsResult_t_9760(lin_msg.m_pubParam, win_msg->m_pubParam); break; case 0x000c008f: win_msg->m_cubParam = sizeof(struct winValidateAuthTicketResponse_t_12); win_msg->m_pubParam = HeapAlloc(GetProcessHeap(), 0, win_msg->m_cubParam); cb_ValidateAuthTicketResponse_t_12(lin_msg.m_pubParam, win_msg->m_pubParam); break; case 0x26100526: win_msg->m_cubParam = sizeof(struct winRemoteStorageGetPublishedFileDetailsResult_t_9744); win_msg->m_pubParam = HeapAlloc(GetProcessHeap(), 0, win_msg->m_cubParam); cb_RemoteStorageGetPublishedFileDetailsResult_t_9744(lin_msg.m_pubParam, win_msg->m_pubParam); break; @@ -206,6 +208,7 @@ case 0x000c0524: win_msg->m_cubParam = sizeof(struct winRemoteStorageUpdatePubli case 0x02640527: win_msg->m_cubParam = sizeof(struct winRemoteStorageEnumerateWorkshopFilesResult_t_612); win_msg->m_pubParam = HeapAlloc(GetProcessHeap(), 0, win_msg->m_cubParam); cb_RemoteStorageEnumerateWorkshopFilesResult_t_612(lin_msg.m_pubParam, win_msg->m_pubParam); break; case 0x00040521: win_msg->m_cubParam = sizeof(struct winRemoteStorageSubscribePublishedFileResult_t_4); win_msg->m_pubParam = HeapAlloc(GetProcessHeap(), 0, win_msg->m_cubParam); cb_RemoteStorageSubscribePublishedFileResult_t_4(lin_msg.m_pubParam, win_msg->m_pubParam); break; case 0x00040523: win_msg->m_cubParam = sizeof(struct winRemoteStorageUnsubscribePublishedFileResult_t_4); win_msg->m_pubParam = HeapAlloc(GetProcessHeap(), 0, win_msg->m_cubParam); cb_RemoteStorageUnsubscribePublishedFileResult_t_4(lin_msg.m_pubParam, win_msg->m_pubParam); break; +case 0x260c0526: win_msg->m_cubParam = sizeof(struct winRemoteStorageGetPublishedFileDetailsResult_t_9740); win_msg->m_pubParam = HeapAlloc(GetProcessHeap(), 0, win_msg->m_cubParam); cb_RemoteStorageGetPublishedFileDetailsResult_t_9740(lin_msg.m_pubParam, win_msg->m_pubParam); break; case 0x250c0526: win_msg->m_cubParam = sizeof(struct winRemoteStorageGetPublishedFileDetailsResult_t_9484); win_msg->m_pubParam = HeapAlloc(GetProcessHeap(), 0, win_msg->m_cubParam); cb_RemoteStorageGetPublishedFileDetailsResult_t_9484(lin_msg.m_pubParam, win_msg->m_pubParam); break; case 0x001000d3: win_msg->m_cubParam = sizeof(struct winComputeNewPlayerCompatibilityResult_t_16); win_msg->m_pubParam = HeapAlloc(GetProcessHeap(), 0, win_msg->m_cubParam); cb_ComputeNewPlayerCompatibilityResult_t_16(lin_msg.m_pubParam, win_msg->m_pubParam); break; case 0x06c4051e: win_msg->m_cubParam = sizeof(struct winRemoteStorageGetPublishedFileDetailsResult_t_1732); win_msg->m_pubParam = HeapAlloc(GetProcessHeap(), 0, win_msg->m_cubParam); cb_RemoteStorageGetPublishedFileDetailsResult_t_1732(lin_msg.m_pubParam, win_msg->m_pubParam); break; diff --git a/lsteamclient/struct_converters.h b/lsteamclient/struct_converters.h index a27629f8..99e11294 100644 --- a/lsteamclient/struct_converters.h +++ b/lsteamclient/struct_converters.h @@ -1698,6 +1698,14 @@ struct winHTML_NewWindow_t_24 { #pragma pack( pop ) extern void cb_HTML_NewWindow_t_24(void *l, void *w); +#pragma pack( push, 8 ) +struct winSteamUGCRequestUGCDetailsResult_t_9764 { + SteamUGCDetails_t m_details; + bool m_bCachedData; +} __attribute__ ((ms_struct)); +#pragma pack( pop ) +extern void cb_SteamUGCRequestUGCDetailsResult_t_9764(void *l, void *w); + #pragma pack( push, 8 ) struct winFavoritesListChanged_t_24 { uint32 m_nIP; @@ -1718,6 +1726,16 @@ struct winRemoteStorageFileShareResult_t_12 { #pragma pack( pop ) extern void cb_RemoteStorageFileShareResult_t_12(void *l, void *w); +#pragma pack( push, 8 ) +struct winSteamUGCQueryCompleted_t_20 { + UGCQueryHandle_t m_handle; + EResult m_eResult; + uint32 m_unNumResultsReturned; + uint32 m_unTotalMatchingResults; +} __attribute__ ((ms_struct)); +#pragma pack( pop ) +extern void cb_SteamUGCQueryCompleted_t_20(void *l, void *w); + #pragma pack( push, 8 ) struct winSteamUGCRequestUGCDetailsResult_t_9760 { SteamUGCDetails_t m_details; @@ -1807,6 +1825,31 @@ struct winRemoteStorageUnsubscribePublishedFileResult_t_4 { #pragma pack( pop ) extern void cb_RemoteStorageUnsubscribePublishedFileResult_t_4(void *l, void *w); +#pragma pack( push, 8 ) +struct winRemoteStorageGetPublishedFileDetailsResult_t_9740 { + EResult m_eResult; + PublishedFileId_t m_nPublishedFileId; + AppId_t m_nCreatorAppID; + AppId_t m_nConsumerAppID; + char m_rgchTitle[129]; + char m_rgchDescription[8000]; + UGCHandle_t m_hFile; + UGCHandle_t m_hPreviewFile; + uint64 m_ulSteamIDOwner; + uint32 m_rtimeCreated; + uint32 m_rtimeUpdated; + ERemoteStoragePublishedFileVisibility m_eVisibility; + bool m_bBanned; + char m_rgchTags[1025]; + bool m_bTagsTruncated; + char m_pchFileName[260]; + int32 m_nFileSize; + int32 m_nPreviewFileSize; + char m_rgchURL[256]; +} __attribute__ ((ms_struct)); +#pragma pack( pop ) +extern void cb_RemoteStorageGetPublishedFileDetailsResult_t_9740(void *l, void *w); + #pragma pack( push, 8 ) struct winRemoteStorageGetPublishedFileDetailsResult_t_9484 { EResult m_eResult; diff --git a/lsteamclient/struct_converters_128.cpp b/lsteamclient/struct_converters_128.cpp index de0308c3..1637f3c0 100644 --- a/lsteamclient/struct_converters_128.cpp +++ b/lsteamclient/struct_converters_128.cpp @@ -41,6 +41,24 @@ void cb_RemoteStorageFileShareResult_t_12(void *l, void *w) win->m_hFile = lin->m_hFile; } +#pragma pack( push, 8 ) +struct winSteamUGCQueryCompleted_t_20 { + UGCQueryHandle_t m_handle; + EResult m_eResult; + uint32 m_unNumResultsReturned; + uint32 m_unTotalMatchingResults; +} __attribute__ ((ms_struct)); +#pragma pack( pop ) +void cb_SteamUGCQueryCompleted_t_20(void *l, void *w) +{ + SteamUGCQueryCompleted_t *lin = (SteamUGCQueryCompleted_t *)l; + struct winSteamUGCQueryCompleted_t_20 *win = (struct winSteamUGCQueryCompleted_t_20 *)w; + win->m_handle = lin->m_handle; + win->m_eResult = lin->m_eResult; + win->m_unNumResultsReturned = lin->m_unNumResultsReturned; + win->m_unTotalMatchingResults = lin->m_unTotalMatchingResults; +} + #pragma pack( push, 8 ) struct winSteamUGCRequestUGCDetailsResult_t_9760 { SteamUGCDetails_t m_details;