From 79111c35e6eecda9b2cdec5f49b3923b25bff167 Mon Sep 17 00:00:00 2001 From: Amine Khaldi Date: Tue, 21 Feb 2017 09:04:05 +0000 Subject: [PATCH] * Revert r73869 because wmi was mentioned nowhere in CORE-9111, nor in our tree restructure wiki, nor any developers discussions. This is the ReactOS trunk, not a branch. svn path=/trunk/; revision=73870 --- reactos/base/CMakeLists.txt | 1 - .../base/applications/cmdutils/CMakeLists.txt | 2 + .../cmdutils/mofcomp/CMakeLists.txt | 6 + .../applications/cmdutils/mofcomp/mofcomp.c | 29 + .../applications/cmdutils/wmic/CMakeLists.txt | 6 + .../applications/cmdutils/wmic/lang/de-DE.rc | 9 + .../applications/cmdutils/wmic/lang/en-US.rc | 9 + .../applications/cmdutils/wmic/lang/ro-RO.rc | 11 + .../applications/cmdutils/wmic/lang/ru-RU.rc | 9 + .../applications/cmdutils/wmic/lang/sq-AL.rc | 13 + .../applications/cmdutils/wmic/lang/tr-TR.rc | 11 + .../applications/cmdutils/wmic/lang/zh-CN.rc | 11 + .../applications/cmdutils/wmic/lang/zh-TW.rc | 11 + .../base/applications/cmdutils/wmic/main.c | 313 ++ .../base/applications/cmdutils/wmic/wmic.h | 24 + .../base/applications/cmdutils/wmic/wmic.rc | 54 + reactos/base/services/CMakeLists.txt | 1 + reactos/base/services/wmisvc/CMakeLists.txt | 10 + reactos/base/services/wmisvc/wmisvc.c | 157 + reactos/base/services/wmisvc/wmisvc.rc | 5 + reactos/base/services/wmisvc/wmisvc.spec | 1 + reactos/boot/bootdata/hivesft.inf | 7 + reactos/boot/bootdata/hivesys.inf | 12 + reactos/dll/win32/CMakeLists.txt | 5 + reactos/dll/win32/framedyn/CMakeLists.txt | 24 + reactos/dll/win32/framedyn/alias_gcc.s | 98 + reactos/dll/win32/framedyn/chstring.cpp | 1404 ++++++++ reactos/dll/win32/framedyn/framedyn.spec | 778 ++++ reactos/dll/win32/framedyn/main.c | 29 + reactos/dll/win32/framedyn/provider.cpp | 57 + reactos/dll/win32/wbemdisp/CMakeLists.txt | 32 + reactos/dll/win32/wbemdisp/guid.c | 18 + reactos/dll/win32/wbemdisp/locator.c | 1658 +++++++++ reactos/dll/win32/wbemdisp/main.c | 551 +++ reactos/dll/win32/wbemdisp/wbemdisp.rc | 3 + reactos/dll/win32/wbemdisp/wbemdisp.spec | 4 + .../dll/win32/wbemdisp/wbemdisp_classes.idl | 29 + .../dll/win32/wbemdisp/wbemdisp_classes.rgs | 24 + reactos/dll/win32/wbemdisp/wbemdisp_private.h | 56 + reactos/dll/win32/wbemdisp/wbemdisp_tlb.idl | 23 + reactos/dll/win32/wbemdisp/wbemdisp_tlb.rgs | 139 + reactos/dll/win32/wbemprox/CMakeLists.txt | 37 + reactos/dll/win32/wbemprox/builtin.c | 3157 +++++++++++++++++ reactos/dll/win32/wbemprox/class.c | 1030 ++++++ reactos/dll/win32/wbemprox/guid.c | 16 + reactos/dll/win32/wbemprox/main.c | 155 + reactos/dll/win32/wbemprox/process.c | 101 + reactos/dll/win32/wbemprox/qualifier.c | 264 ++ reactos/dll/win32/wbemprox/query.c | 1064 ++++++ reactos/dll/win32/wbemprox/reg.c | 374 ++ reactos/dll/win32/wbemprox/security.c | 209 ++ reactos/dll/win32/wbemprox/service.c | 269 ++ reactos/dll/win32/wbemprox/services.c | 888 +++++ reactos/dll/win32/wbemprox/table.c | 418 +++ reactos/dll/win32/wbemprox/wbemlocator.c | 217 ++ reactos/dll/win32/wbemprox/wbemprox.idl | 35 + reactos/dll/win32/wbemprox/wbemprox.rc | 1 + reactos/dll/win32/wbemprox/wbemprox.rgs | 17 + reactos/dll/win32/wbemprox/wbemprox.spec | 4 + reactos/dll/win32/wbemprox/wbemprox_private.h | 315 ++ reactos/dll/win32/wbemprox/wql.tab.c | 2275 ++++++++++++ reactos/dll/win32/wbemprox/wql.y | 701 ++++ reactos/dll/win32/wmi/CMakeLists.txt | 12 + reactos/dll/win32/wmi/wmi.rc | 5 + reactos/dll/win32/wmi/wmi.spec | 45 + reactos/dll/win32/wmiutils/CMakeLists.txt | 17 + reactos/dll/win32/wmiutils/main.c | 171 + reactos/dll/win32/wmiutils/path.c | 1294 +++++++ reactos/dll/win32/wmiutils/statuscode.c | 150 + reactos/dll/win32/wmiutils/wmiutils.rc | 2 + reactos/dll/win32/wmiutils/wmiutils.spec | 4 + .../dll/win32/wmiutils/wmiutils_classes.idl | 33 + .../dll/win32/wmiutils/wmiutils_classes.rgs | 17 + reactos/dll/win32/wmiutils/wmiutils_private.h | 53 + reactos/media/doc/README.WINE | 14 +- 75 files changed, 18998 insertions(+), 10 deletions(-) create mode 100644 reactos/base/applications/cmdutils/mofcomp/CMakeLists.txt create mode 100644 reactos/base/applications/cmdutils/mofcomp/mofcomp.c create mode 100644 reactos/base/applications/cmdutils/wmic/CMakeLists.txt create mode 100644 reactos/base/applications/cmdutils/wmic/lang/de-DE.rc create mode 100644 reactos/base/applications/cmdutils/wmic/lang/en-US.rc create mode 100644 reactos/base/applications/cmdutils/wmic/lang/ro-RO.rc create mode 100644 reactos/base/applications/cmdutils/wmic/lang/ru-RU.rc create mode 100644 reactos/base/applications/cmdutils/wmic/lang/sq-AL.rc create mode 100644 reactos/base/applications/cmdutils/wmic/lang/tr-TR.rc create mode 100644 reactos/base/applications/cmdutils/wmic/lang/zh-CN.rc create mode 100644 reactos/base/applications/cmdutils/wmic/lang/zh-TW.rc create mode 100644 reactos/base/applications/cmdutils/wmic/main.c create mode 100644 reactos/base/applications/cmdutils/wmic/wmic.h create mode 100644 reactos/base/applications/cmdutils/wmic/wmic.rc create mode 100644 reactos/base/services/wmisvc/CMakeLists.txt create mode 100644 reactos/base/services/wmisvc/wmisvc.c create mode 100644 reactos/base/services/wmisvc/wmisvc.rc create mode 100644 reactos/base/services/wmisvc/wmisvc.spec create mode 100644 reactos/dll/win32/framedyn/CMakeLists.txt create mode 100644 reactos/dll/win32/framedyn/alias_gcc.s create mode 100644 reactos/dll/win32/framedyn/chstring.cpp create mode 100644 reactos/dll/win32/framedyn/framedyn.spec create mode 100644 reactos/dll/win32/framedyn/main.c create mode 100644 reactos/dll/win32/framedyn/provider.cpp create mode 100644 reactos/dll/win32/wbemdisp/CMakeLists.txt create mode 100644 reactos/dll/win32/wbemdisp/guid.c create mode 100644 reactos/dll/win32/wbemdisp/locator.c create mode 100644 reactos/dll/win32/wbemdisp/main.c create mode 100644 reactos/dll/win32/wbemdisp/wbemdisp.rc create mode 100644 reactos/dll/win32/wbemdisp/wbemdisp.spec create mode 100644 reactos/dll/win32/wbemdisp/wbemdisp_classes.idl create mode 100644 reactos/dll/win32/wbemdisp/wbemdisp_classes.rgs create mode 100644 reactos/dll/win32/wbemdisp/wbemdisp_private.h create mode 100644 reactos/dll/win32/wbemdisp/wbemdisp_tlb.idl create mode 100644 reactos/dll/win32/wbemdisp/wbemdisp_tlb.rgs create mode 100644 reactos/dll/win32/wbemprox/CMakeLists.txt create mode 100644 reactos/dll/win32/wbemprox/builtin.c create mode 100644 reactos/dll/win32/wbemprox/class.c create mode 100644 reactos/dll/win32/wbemprox/guid.c create mode 100644 reactos/dll/win32/wbemprox/main.c create mode 100644 reactos/dll/win32/wbemprox/process.c create mode 100644 reactos/dll/win32/wbemprox/qualifier.c create mode 100644 reactos/dll/win32/wbemprox/query.c create mode 100644 reactos/dll/win32/wbemprox/reg.c create mode 100644 reactos/dll/win32/wbemprox/security.c create mode 100644 reactos/dll/win32/wbemprox/service.c create mode 100644 reactos/dll/win32/wbemprox/services.c create mode 100644 reactos/dll/win32/wbemprox/table.c create mode 100644 reactos/dll/win32/wbemprox/wbemlocator.c create mode 100644 reactos/dll/win32/wbemprox/wbemprox.idl create mode 100644 reactos/dll/win32/wbemprox/wbemprox.rc create mode 100644 reactos/dll/win32/wbemprox/wbemprox.rgs create mode 100644 reactos/dll/win32/wbemprox/wbemprox.spec create mode 100644 reactos/dll/win32/wbemprox/wbemprox_private.h create mode 100644 reactos/dll/win32/wbemprox/wql.tab.c create mode 100644 reactos/dll/win32/wbemprox/wql.y create mode 100644 reactos/dll/win32/wmi/CMakeLists.txt create mode 100644 reactos/dll/win32/wmi/wmi.rc create mode 100644 reactos/dll/win32/wmi/wmi.spec create mode 100644 reactos/dll/win32/wmiutils/CMakeLists.txt create mode 100644 reactos/dll/win32/wmiutils/main.c create mode 100644 reactos/dll/win32/wmiutils/path.c create mode 100644 reactos/dll/win32/wmiutils/statuscode.c create mode 100644 reactos/dll/win32/wmiutils/wmiutils.rc create mode 100644 reactos/dll/win32/wmiutils/wmiutils.spec create mode 100644 reactos/dll/win32/wmiutils/wmiutils_classes.idl create mode 100644 reactos/dll/win32/wmiutils/wmiutils_classes.rgs create mode 100644 reactos/dll/win32/wmiutils/wmiutils_private.h diff --git a/reactos/base/CMakeLists.txt b/reactos/base/CMakeLists.txt index 01732d6e3cb..5dafa0b5aff 100644 --- a/reactos/base/CMakeLists.txt +++ b/reactos/base/CMakeLists.txt @@ -4,4 +4,3 @@ add_subdirectory(services) add_subdirectory(setup) add_subdirectory(shell) add_subdirectory(system) -add_subdirectory(wmi) diff --git a/reactos/base/applications/cmdutils/CMakeLists.txt b/reactos/base/applications/cmdutils/CMakeLists.txt index bd62a1a5b53..07642853147 100644 --- a/reactos/base/applications/cmdutils/CMakeLists.txt +++ b/reactos/base/applications/cmdutils/CMakeLists.txt @@ -9,6 +9,7 @@ add_subdirectory(help) add_subdirectory(hostname) add_subdirectory(lodctr) add_subdirectory(mode) +add_subdirectory(mofcomp) add_subdirectory(more) add_subdirectory(reg) add_subdirectory(schtasks) @@ -16,5 +17,6 @@ add_subdirectory(sort) add_subdirectory(taskkill) add_subdirectory(tree) add_subdirectory(whoami) +add_subdirectory(wmic) add_subdirectory(wscript) add_subdirectory(xcopy) diff --git a/reactos/base/applications/cmdutils/mofcomp/CMakeLists.txt b/reactos/base/applications/cmdutils/mofcomp/CMakeLists.txt new file mode 100644 index 00000000000..4bc16afe9c0 --- /dev/null +++ b/reactos/base/applications/cmdutils/mofcomp/CMakeLists.txt @@ -0,0 +1,6 @@ + +add_executable(mofcomp mofcomp.c) +target_link_libraries(mofcomp wine) +set_module_type(mofcomp win32cui UNICODE) +add_importlibs(mofcomp msvcrt kernel32 ntdll) +add_cd_file(TARGET mofcomp DESTINATION reactos/system32/wbem FOR all) diff --git a/reactos/base/applications/cmdutils/mofcomp/mofcomp.c b/reactos/base/applications/cmdutils/mofcomp/mofcomp.c new file mode 100644 index 00000000000..07698e4eaa0 --- /dev/null +++ b/reactos/base/applications/cmdutils/mofcomp/mofcomp.c @@ -0,0 +1,29 @@ +/* + * Copyright 2010 Hans Leidekker for CodeWeavers + * + * 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 + */ + +#define WIN32_LEAN_AND_MEAN +#include + +#include +WINE_DEFAULT_DEBUG_CHANNEL(mofcomp); + +int wmain( int argc, const WCHAR *argv[] ) +{ + WINE_FIXME("stub\n"); + return 0; +} diff --git a/reactos/base/applications/cmdutils/wmic/CMakeLists.txt b/reactos/base/applications/cmdutils/wmic/CMakeLists.txt new file mode 100644 index 00000000000..8da30f4ec1d --- /dev/null +++ b/reactos/base/applications/cmdutils/wmic/CMakeLists.txt @@ -0,0 +1,6 @@ + +add_executable(wmic main.c wmic.rc) +target_link_libraries(wmic wine) +set_module_type(wmic win32cui UNICODE) +add_importlibs(wmic oleaut32 ole32 user32 msvcrt kernel32 ntdll) +add_cd_file(TARGET wmic DESTINATION reactos/system32/wbem FOR all) diff --git a/reactos/base/applications/cmdutils/wmic/lang/de-DE.rc b/reactos/base/applications/cmdutils/wmic/lang/de-DE.rc new file mode 100644 index 00000000000..76082a449b6 --- /dev/null +++ b/reactos/base/applications/cmdutils/wmic/lang/de-DE.rc @@ -0,0 +1,9 @@ +LANGUAGE LANG_GERMAN, SUBLANG_NEUTRAL + +STRINGTABLE +{ + STRING_CMDLINE_NOT_SUPPORTED, "Fehler: Befehlszeile nicht unterstützt\n" + STRING_ALIAS_NOT_FOUND, "Fehler: Alias nicht gefunden\n" + STRING_INVALID_QUERY, "Fehler: Ungültige Abfrage\n" + STRING_INVALID_PATH, "Invalid syntax for PATH\n" +} diff --git a/reactos/base/applications/cmdutils/wmic/lang/en-US.rc b/reactos/base/applications/cmdutils/wmic/lang/en-US.rc new file mode 100644 index 00000000000..275a99d37cf --- /dev/null +++ b/reactos/base/applications/cmdutils/wmic/lang/en-US.rc @@ -0,0 +1,9 @@ +LANGUAGE LANG_ENGLISH, SUBLANG_DEFAULT + +STRINGTABLE +{ + STRING_CMDLINE_NOT_SUPPORTED, "Error: Command line not supported\n" + STRING_ALIAS_NOT_FOUND, "Error: Alias not found\n" + STRING_INVALID_QUERY, "Error: Invalid query\n" + STRING_INVALID_PATH, "Invalid syntax for PATH\n" +} diff --git a/reactos/base/applications/cmdutils/wmic/lang/ro-RO.rc b/reactos/base/applications/cmdutils/wmic/lang/ro-RO.rc new file mode 100644 index 00000000000..11c101ee374 --- /dev/null +++ b/reactos/base/applications/cmdutils/wmic/lang/ro-RO.rc @@ -0,0 +1,11 @@ +/* Translator: Ștefan Fulea (stefan dot fulea at mail dot md) */ + +LANGUAGE LANG_ROMANIAN, SUBLANG_NEUTRAL + +STRINGTABLE +{ + STRING_CMDLINE_NOT_SUPPORTED, "Eroare: Comandă nerecunoscută.\n" + STRING_ALIAS_NOT_FOUND, "Eroare: Alias necunoscut.\n" + STRING_INVALID_QUERY, "Eroare: Cerere nevalidă.\n" + STRING_INVALID_PATH, "Conținutul din «PATH» este sintactic nevalid.\n" +} diff --git a/reactos/base/applications/cmdutils/wmic/lang/ru-RU.rc b/reactos/base/applications/cmdutils/wmic/lang/ru-RU.rc new file mode 100644 index 00000000000..46bc7597225 --- /dev/null +++ b/reactos/base/applications/cmdutils/wmic/lang/ru-RU.rc @@ -0,0 +1,9 @@ +LANGUAGE LANG_RUSSIAN, SUBLANG_DEFAULT + +STRINGTABLE +{ + STRING_CMDLINE_NOT_SUPPORTED, "Ошибка: Командная строка не поддерживается\n" + STRING_ALIAS_NOT_FOUND, "Ошибка: Псевдоним не найден\n" + STRING_INVALID_QUERY, "Ошибка: Неверный запрос\n" + STRING_INVALID_PATH, "Неверный синтаксис PATH\n" +} diff --git a/reactos/base/applications/cmdutils/wmic/lang/sq-AL.rc b/reactos/base/applications/cmdutils/wmic/lang/sq-AL.rc new file mode 100644 index 00000000000..72fe2c15400 --- /dev/null +++ b/reactos/base/applications/cmdutils/wmic/lang/sq-AL.rc @@ -0,0 +1,13 @@ +/* TRANSLATOR : Ardit Dani (Ard1t) (ardit.dani@gmail.com) +* DATE OF TR: 29-11-2013 +*/ + +LANGUAGE LANG_ALBANIAN, SUBLANG_NEUTRAL + +STRINGTABLE +{ + STRING_CMDLINE_NOT_SUPPORTED, "Gabim: Linja e komandave jo e mbështetur\n" + STRING_ALIAS_NOT_FOUND, "Gabim: Pseudonimi nuk u gjend\n" + STRING_INVALID_QUERY, "Gabim: Kërkim pa vlere\n" + STRING_INVALID_PATH, "Invalid syntax for PATH\n" +} diff --git a/reactos/base/applications/cmdutils/wmic/lang/tr-TR.rc b/reactos/base/applications/cmdutils/wmic/lang/tr-TR.rc new file mode 100644 index 00000000000..c636b412235 --- /dev/null +++ b/reactos/base/applications/cmdutils/wmic/lang/tr-TR.rc @@ -0,0 +1,11 @@ +/* TRANSLATOR: 2015 Erdem Ersoy (eersoy93) (erdemersoy@live.com) */ + +LANGUAGE LANG_TURKISH, SUBLANG_NEUTRAL + +STRINGTABLE +{ + STRING_CMDLINE_NOT_SUPPORTED, "Yanlışlık: Komut yatacı desteklenmiyor\n" + STRING_ALIAS_NOT_FOUND, "Yanlışlık: Başka ad bulunamadı\n" + STRING_INVALID_QUERY, "Yanlışlık: Geçersiz sorgu\n" + STRING_INVALID_PATH, "YOL için geçersiz söz dizimi.\n" +} diff --git a/reactos/base/applications/cmdutils/wmic/lang/zh-CN.rc b/reactos/base/applications/cmdutils/wmic/lang/zh-CN.rc new file mode 100644 index 00000000000..525ab38482c --- /dev/null +++ b/reactos/base/applications/cmdutils/wmic/lang/zh-CN.rc @@ -0,0 +1,11 @@ +/* Simplified Chinese translation by Henry Tang Ih 2016 (henrytang2@hotmail.com) */ + +LANGUAGE LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED + +STRINGTABLE +{ + STRING_CMDLINE_NOT_SUPPORTED, "错误: 不支持的命令行\n" + STRING_ALIAS_NOT_FOUND, "错误: 别名未找到\n" + STRING_INVALID_QUERY, "错误: 无效的查询\n" + STRING_INVALID_PATH, "Invalid syntax for PATH\n" +} diff --git a/reactos/base/applications/cmdutils/wmic/lang/zh-TW.rc b/reactos/base/applications/cmdutils/wmic/lang/zh-TW.rc new file mode 100644 index 00000000000..bdd6653902f --- /dev/null +++ b/reactos/base/applications/cmdutils/wmic/lang/zh-TW.rc @@ -0,0 +1,11 @@ +/* Traditional Chinese translation by Henry Tang Ih 2016 (henrytang2@hotmail.com) */ + +LANGUAGE LANG_CHINESE, SUBLANG_CHINESE_TRADITIONAL + +STRINGTABLE +{ + STRING_CMDLINE_NOT_SUPPORTED, "錯誤: 不支援的命令列\n" + STRING_ALIAS_NOT_FOUND, "錯誤: 別名未找到\n" + STRING_INVALID_QUERY, "錯誤: 無效的查詢\n" + STRING_INVALID_PATH, "Invalid syntax for PATH\n" +} \ No newline at end of file diff --git a/reactos/base/applications/cmdutils/wmic/main.c b/reactos/base/applications/cmdutils/wmic/main.c new file mode 100644 index 00000000000..e84aa8ff0d1 --- /dev/null +++ b/reactos/base/applications/cmdutils/wmic/main.c @@ -0,0 +1,313 @@ +/* + * Copyright 2010 Louis Lenders + * Copyright 2012 Hans Leidekker for CodeWeavers + * + * 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 + */ + +#define COBJMACROS + +//#include +//#include "windows.h" +//#include "ocidl.h" +#include +//#include "objidl.h" +#include +#include "wmic.h" + +#include +#include + +WINE_DEFAULT_DEBUG_CHANNEL(wmic); + +static const WCHAR biosW[] = + {'b','i','o','s',0}; +static const WCHAR computersystemW[] = + {'c','o','m','p','u','t','e','r','s','y','s','t','e','m',0}; +static const WCHAR cpuW[] = + {'c','p','u',0}; +static const WCHAR logicaldiskW[] = + {'L','o','g','i','c','a','l','D','i','s','k',0}; +static const WCHAR nicW[] = + {'n','i','c',0}; +static const WCHAR osW[] = + {'o','s',0}; +static const WCHAR processW[] = + {'p','r','o','c','e','s','s',0}; + +static const WCHAR win32_biosW[] = + {'W','i','n','3','2','_','B','I','O','S',0}; +static const WCHAR win32_computersystemW[] = + {'W','i','n','3','2','_','C','o','m','p','u','t','e','r','S','y','s','t','e','m',0}; +static const WCHAR win32_logicaldiskW[] = + {'W','i','n','3','2','_','L','o','g','i','c','a','l','D','i','s','k',0}; +static const WCHAR win32_networkadapterW[] = + {'W','i','n','3','2','_','N','e','t','w','o','r','k','A','d','a','p','t','e','r',0}; +static const WCHAR win32_operatingsystemW[] = + {'W','i','n','3','2','_','O','p','e','r','a','t','i','n','g','S','y','s','t','e','m',0}; +static const WCHAR win32_processW[] = + {'W','i','n','3','2','_','P','r','o','c','e','s','s',0}; +static const WCHAR win32_processorW[] = + {'W','i','n','3','2','_','P','r','o','c','e','s','s','o','r',0}; + +static const struct +{ + const WCHAR *alias; + const WCHAR *class; +} +alias_map[] = +{ + { biosW, win32_biosW }, + { computersystemW, win32_computersystemW }, + { cpuW, win32_processorW }, + { logicaldiskW, win32_logicaldiskW }, + { nicW, win32_networkadapterW }, + { osW, win32_operatingsystemW }, + { processW, win32_processW } +}; + +static const WCHAR *find_class( const WCHAR *alias ) +{ + unsigned int i; + + for (i = 0; i < sizeof(alias_map)/sizeof(alias_map[0]); i++) + { + if (!strcmpiW( alias, alias_map[i].alias )) return alias_map[i].class; + } + return NULL; +} + +static inline WCHAR *strdupW( const WCHAR *src ) +{ + WCHAR *dst; + if (!src) return NULL; + if (!(dst = HeapAlloc( GetProcessHeap(), 0, (strlenW( src ) + 1) * sizeof(WCHAR) ))) return NULL; + strcpyW( dst, src ); + return dst; +} + +static WCHAR *find_prop( IWbemClassObject *class, const WCHAR *prop ) +{ + SAFEARRAY *sa; + WCHAR *ret = NULL; + LONG i, last_index = 0; + BSTR str; + + if (IWbemClassObject_GetNames( class, NULL, WBEM_FLAG_ALWAYS, NULL, &sa ) != S_OK) return NULL; + + SafeArrayGetUBound( sa, 1, &last_index ); + for (i = 0; i <= last_index; i++) + { + SafeArrayGetElement( sa, &i, &str ); + if (!strcmpiW( str, prop )) + { + ret = strdupW( str ); + break; + } + } + SafeArrayDestroy( sa ); + return ret; +} + +static int output_string( const WCHAR *msg, ... ) +{ + va_list va_args; + int wlen; + DWORD count, ret; + WCHAR buffer[8192]; + + va_start( va_args, msg ); + vsprintfW( buffer, msg, va_args ); + va_end( va_args ); + + wlen = strlenW( buffer ); + ret = WriteConsoleW( GetStdHandle(STD_OUTPUT_HANDLE), buffer, wlen, &count, NULL ); + if (!ret) + { + DWORD len; + char *msgA; + + /* On Windows WriteConsoleW() fails if the output is redirected. So fall + * back to WriteFile(), assuming the console encoding is still the right + * one in that case. + */ + len = WideCharToMultiByte( GetConsoleOutputCP(), 0, buffer, wlen, NULL, 0, NULL, NULL ); + if (!(msgA = HeapAlloc( GetProcessHeap(), 0, len * sizeof(char) ))) return 0; + + WideCharToMultiByte( GetConsoleOutputCP(), 0, buffer, wlen, msgA, len, NULL, NULL ); + WriteFile( GetStdHandle(STD_OUTPUT_HANDLE), msgA, len, &count, FALSE ); + HeapFree( GetProcessHeap(), 0, msgA ); + } + return count; +} + +static int output_message( int msg ) +{ + static const WCHAR fmtW[] = {'%','s',0}; + WCHAR buffer[8192]; + + LoadStringW( GetModuleHandleW(NULL), msg, buffer, sizeof(buffer)/sizeof(WCHAR) ); + return output_string( fmtW, buffer ); +} + +static int query_prop( const WCHAR *class, const WCHAR *propname ) +{ + static const WCHAR select_allW[] = {'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ',0}; + static const WCHAR cimv2W[] = {'R','O','O','T','\\','C','I','M','V','2',0}; + static const WCHAR wqlW[] = {'W','Q','L',0}; + static const WCHAR newlineW[] = {'\n',0}; + static const WCHAR fmtW[] = {'%','s','\n',0}; + HRESULT hr; + IWbemLocator *locator = NULL; + IWbemServices *services = NULL; + IEnumWbemClassObject *result = NULL; + LONG flags = WBEM_FLAG_RETURN_IMMEDIATELY | WBEM_FLAG_FORWARD_ONLY; + BSTR path = NULL, wql = NULL, query = NULL; + WCHAR *prop = NULL; + BOOL first = TRUE; + int len, ret = -1; + + WINE_TRACE("%s, %s\n", debugstr_w(class), debugstr_w(propname)); + + CoInitialize( NULL ); + CoInitializeSecurity( NULL, -1, NULL, NULL, RPC_C_AUTHN_LEVEL_DEFAULT, + RPC_C_IMP_LEVEL_IMPERSONATE, NULL, EOAC_NONE, NULL ); + + hr = CoCreateInstance( &CLSID_WbemLocator, NULL, CLSCTX_INPROC_SERVER, &IID_IWbemLocator, + (void **)&locator ); + if (hr != S_OK) goto done; + + if (!(path = SysAllocString( cimv2W ))) goto done; + hr = IWbemLocator_ConnectServer( locator, path, NULL, NULL, NULL, 0, NULL, NULL, &services ); + if (hr != S_OK) goto done; + + len = strlenW( class ) + sizeof(select_allW) / sizeof(select_allW[0]); + if (!(query = SysAllocStringLen( NULL, len ))) goto done; + strcpyW( query, select_allW ); + strcatW( query, class ); + + if (!(wql = SysAllocString( wqlW ))) goto done; + hr = IWbemServices_ExecQuery( services, wql, query, flags, NULL, &result ); + if (hr != S_OK) goto done; + + for (;;) + { + IWbemClassObject *obj; + ULONG count; + VARIANT v; + + IEnumWbemClassObject_Next( result, WBEM_INFINITE, 1, &obj, &count ); + if (!count) break; + + if (first) + { + if (!(prop = find_prop( obj, propname ))) + { + output_message( STRING_INVALID_QUERY ); + goto done; + } + output_string( fmtW, prop ); + first = FALSE; + } + if (IWbemClassObject_Get( obj, prop, 0, &v, NULL, NULL ) == WBEM_S_NO_ERROR) + { + VariantChangeType( &v, &v, 0, VT_BSTR ); + output_string( fmtW, V_BSTR( &v ) ); + VariantClear( &v ); + } + IWbemClassObject_Release( obj ); + } + output_string( newlineW ); + ret = 0; + +done: + if (result) IEnumWbemClassObject_Release( result ); + if (services) IWbemServices_Release( services ); + if (locator) IWbemLocator_Release( locator ); + SysFreeString( path ); + SysFreeString( query ); + SysFreeString( wql ); + HeapFree( GetProcessHeap(), 0, prop ); + CoUninitialize(); + return ret; +} + +int wmain(int argc, WCHAR *argv[]) +{ + static const WCHAR getW[] = {'g','e','t',0}; + static const WCHAR quitW[] = {'q','u','i','t',0}; + static const WCHAR exitW[] = {'e','x','i','t',0}; + static const WCHAR pathW[] = {'p','a','t','h',0}; + static const WCHAR classW[] = {'c','l','a','s','s',0}; + static const WCHAR contextW[] = {'c','o','n','t','e','x','t',0}; + + const WCHAR *class; + const WCHAR *value; + int i; + + if (argc == 1) + goto not_supported; + + for (i = 1; i < argc && argv[i][0] == '/'; i++) + WINE_FIXME("command line switch %s not supported\n", debugstr_w(argv[i])); + + if (i >= argc) + goto not_supported; + + if (!strcmpiW( argv[i], quitW ) || + !strcmpiW( argv[i], exitW )) + { + return 0; + } + else if (!strcmpiW( argv[i], classW) || + !strcmpiW( argv[i], contextW)) + { + WINE_FIXME("command %s not supported\n", debugstr_w(argv[i])); + goto not_supported; + } + else if (!strcmpiW( argv[i], pathW)) + { + if (++i >= argc) + { + output_message( STRING_INVALID_PATH ); + return 1; + } + class = argv[i]; + } + else + { + class = find_class( argv[i] ); + if (!class) + { + output_message( STRING_ALIAS_NOT_FOUND ); + return 1; + } + } + + if (++i >= argc) + goto not_supported; + + if (!strcmpiW( argv[i], getW)) + { + if (++i >= argc) + goto not_supported; + value = argv[i]; + return query_prop( class, value ); + } + +not_supported: + output_message( STRING_CMDLINE_NOT_SUPPORTED ); + return 1; +} diff --git a/reactos/base/applications/cmdutils/wmic/wmic.h b/reactos/base/applications/cmdutils/wmic/wmic.h new file mode 100644 index 00000000000..27272706af5 --- /dev/null +++ b/reactos/base/applications/cmdutils/wmic/wmic.h @@ -0,0 +1,24 @@ +/* + * Copyright 2012 Hans Leidekker for CodeWeavers + * + * 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 + +#define STRING_CMDLINE_NOT_SUPPORTED 101 +#define STRING_ALIAS_NOT_FOUND 102 +#define STRING_INVALID_QUERY 103 +#define STRING_INVALID_PATH 104 diff --git a/reactos/base/applications/cmdutils/wmic/wmic.rc b/reactos/base/applications/cmdutils/wmic/wmic.rc new file mode 100644 index 00000000000..a830a7bbe05 --- /dev/null +++ b/reactos/base/applications/cmdutils/wmic/wmic.rc @@ -0,0 +1,54 @@ +/* + * Copyright 2012 Hans Leidekker for CodeWeavers + * + * 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 "wmic.h" + +LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL + +#define REACTOS_STR_FILE_DESCRIPTION "ReactOS WMI command line" +#define REACTOS_STR_INTERNAL_NAME "wmic" +#define REACTOS_STR_ORIGINAL_FILENAME "wmic.exe" +#include + +/* UTF-8 */ +#pragma code_page(65001) + +#ifdef LANGUAGE_DE_DE + #include "lang/de-DE.rc" +#endif +#ifdef LANGUAGE_EN_US + #include "lang/en-US.rc" +#endif +#ifdef LANGUAGE_RO_RO + #include "lang/ro-RO.rc" +#endif +#ifdef LANGUAGE_RU_RU + #include "lang/ru-RU.rc" +#endif +#ifdef LANGUAGE_SQ_AL + #include "lang/sq-AL.rc" +#endif +#ifdef LANGUAGE_TR_TR + #include "lang/tr-TR.rc" +#endif +#ifdef LANGUAGE_ZH_CN + #include "lang/zh-CN.rc" +#endif +#ifdef LANGUAGE_ZH_TW + #include "lang/zh-TW.rc" +#endif \ No newline at end of file diff --git a/reactos/base/services/CMakeLists.txt b/reactos/base/services/CMakeLists.txt index 13773bbb5bf..fa0c0171c9c 100644 --- a/reactos/base/services/CMakeLists.txt +++ b/reactos/base/services/CMakeLists.txt @@ -13,3 +13,4 @@ add_subdirectory(thmsvc) add_subdirectory(umpnpmgr) add_subdirectory(wkssvc) add_subdirectory(wlansvc) +add_subdirectory(wmisvc) diff --git a/reactos/base/services/wmisvc/CMakeLists.txt b/reactos/base/services/wmisvc/CMakeLists.txt new file mode 100644 index 00000000000..3c8b8f9f924 --- /dev/null +++ b/reactos/base/services/wmisvc/CMakeLists.txt @@ -0,0 +1,10 @@ +spec2def(wmisvc.dll wmisvc.spec ADD_IMPORTLIB) + +add_library(wmisvc SHARED + wmisvc.c + wmisvc.rc + ${CMAKE_CURRENT_BINARY_DIR}/wmisvc.def) + +set_module_type(wmisvc win32dll UNICODE) +add_importlibs(wmisvc advapi32 msvcrt kernel32 ntdll) +add_cd_file(TARGET wmisvc DESTINATION reactos/system32/wbem FOR all) diff --git a/reactos/base/services/wmisvc/wmisvc.c b/reactos/base/services/wmisvc/wmisvc.c new file mode 100644 index 00000000000..8ac9d9b7339 --- /dev/null +++ b/reactos/base/services/wmisvc/wmisvc.c @@ -0,0 +1,157 @@ +/* + * ReactOS Services + * Copyright (C) 2015 ReactOS Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ +/* + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS Services + * FILE: base/services/wmisvc/wmisvc.c + * PURPOSE: WMI service + * PROGRAMMER: Pierre Schweitzer + */ + +/* INCLUDES *****************************************************************/ + +#define WIN32_NO_STATUS +#define _INC_WINDOWS +#define COM_NO_WINDOWS_H +#include +#include +#include +#include +#include + +#define NDEBUG +#include + +/* GLOBALS ******************************************************************/ + +static WCHAR ServiceName[] = L"winmgmt"; + +static SERVICE_STATUS_HANDLE ServiceStatusHandle; +static SERVICE_STATUS ServiceStatus; + +/* FUNCTIONS *****************************************************************/ + +static VOID +UpdateServiceStatus(DWORD dwState) +{ + ServiceStatus.dwServiceType = SERVICE_WIN32_OWN_PROCESS; + ServiceStatus.dwCurrentState = dwState; + ServiceStatus.dwControlsAccepted = 0; + ServiceStatus.dwWin32ExitCode = 0; + ServiceStatus.dwServiceSpecificExitCode = 0; + ServiceStatus.dwCheckPoint = 0; + + if (dwState == SERVICE_START_PENDING || + dwState == SERVICE_STOP_PENDING || + dwState == SERVICE_PAUSE_PENDING || + dwState == SERVICE_CONTINUE_PENDING) + ServiceStatus.dwWaitHint = 10000; + else + ServiceStatus.dwWaitHint = 0; + + SetServiceStatus(ServiceStatusHandle, + &ServiceStatus); +} + +static DWORD WINAPI +ServiceControlHandler(DWORD dwControl, + DWORD dwEventType, + LPVOID lpEventData, + LPVOID lpContext) +{ + DPRINT1("ServiceControlHandler() called\n"); + + switch (dwControl) + { + case SERVICE_CONTROL_STOP: + DPRINT1(" SERVICE_CONTROL_STOP received\n"); + UpdateServiceStatus(SERVICE_STOPPED); + return ERROR_SUCCESS; + + case SERVICE_CONTROL_PAUSE: + DPRINT1(" SERVICE_CONTROL_PAUSE received\n"); + UpdateServiceStatus(SERVICE_PAUSED); + return ERROR_SUCCESS; + + case SERVICE_CONTROL_CONTINUE: + DPRINT1(" SERVICE_CONTROL_CONTINUE received\n"); + UpdateServiceStatus(SERVICE_RUNNING); + return ERROR_SUCCESS; + + case SERVICE_CONTROL_INTERROGATE: + DPRINT1(" SERVICE_CONTROL_INTERROGATE received\n"); + SetServiceStatus(ServiceStatusHandle, + &ServiceStatus); + return ERROR_SUCCESS; + + case SERVICE_CONTROL_SHUTDOWN: + DPRINT1(" SERVICE_CONTROL_SHUTDOWN received\n"); + UpdateServiceStatus(SERVICE_STOPPED); + return ERROR_SUCCESS; + + default : + DPRINT1(" Control %lu received\n"); + return ERROR_CALL_NOT_IMPLEMENTED; + } +} + +VOID WINAPI +ServiceMain(DWORD argc, LPTSTR *argv) +{ + UNREFERENCED_PARAMETER(argc); + UNREFERENCED_PARAMETER(argv); + + DPRINT("ServiceMain() called\n"); + + ServiceStatusHandle = RegisterServiceCtrlHandlerExW(ServiceName, + ServiceControlHandler, + NULL); + if (!ServiceStatusHandle) + { + DPRINT1("RegisterServiceCtrlHandlerExW() failed! (Error %lu)\n", GetLastError()); + return; + } + + UpdateServiceStatus(SERVICE_RUNNING); + + do + { + Sleep(1); + } while (1); + + UpdateServiceStatus(SERVICE_STOPPED); +} + +BOOL WINAPI +DllMain(HINSTANCE hinstDLL, + DWORD fdwReason, + LPVOID lpvReserved) +{ + switch (fdwReason) + { + case DLL_PROCESS_ATTACH: + DisableThreadLibraryCalls(hinstDLL); + break; + + case DLL_PROCESS_DETACH: + break; + } + + return TRUE; +} diff --git a/reactos/base/services/wmisvc/wmisvc.rc b/reactos/base/services/wmisvc/wmisvc.rc new file mode 100644 index 00000000000..ba7e6e2327c --- /dev/null +++ b/reactos/base/services/wmisvc/wmisvc.rc @@ -0,0 +1,5 @@ +#define REACTOS_VERSION_DLL +#define REACTOS_STR_FILE_DESCRIPTION "WMI Service" +#define REACTOS_STR_INTERNAL_NAME "wmisvc" +#define REACTOS_STR_ORIGINAL_FILENAME "wmisvc.dll" +#include diff --git a/reactos/base/services/wmisvc/wmisvc.spec b/reactos/base/services/wmisvc/wmisvc.spec new file mode 100644 index 00000000000..1b27fe53864 --- /dev/null +++ b/reactos/base/services/wmisvc/wmisvc.spec @@ -0,0 +1 @@ +@ stdcall ServiceMain(long ptr) diff --git a/reactos/boot/bootdata/hivesft.inf b/reactos/boot/bootdata/hivesft.inf index f7b809f5ce4..85f1a6e65ff 100644 --- a/reactos/boot/bootdata/hivesft.inf +++ b/reactos/boot/bootdata/hivesft.inf @@ -92,6 +92,13 @@ HKLM,"SOFTWARE\Microsoft\Rpc\SecurityService","9",2,"secur32.dll" HKLM,"SOFTWARE\Microsoft\Secure",,0x00000012 +; WBem +HKLM,"SOFTWARE\Microsoft\wbem\ess",,0x00000012 +HKLM,"SOFTWARE\Microsoft\wbem\Transports",,0x00000012 +HKLM,"SOFTWARE\Microsoft\wbem\Scripting",,0x00000012 +HKLM,"SOFTWARE\Microsoft\wbem","Installation Directory",0x00020000,"%SystemRoot%\system32\wbem" +HKLM,"SOFTWARE\Microsoft\wbem","MOF Self-Install Directory",0x00020000,"%SystemRoot%\system32\wbem\mof" + ; HTML Help HKLM,"SOFTWARE\Microsoft\Active Setup\Installed Components\{de5aed00-a4bf-11d1-9948-00c04f98bbc9}",,2,"HTML Help" HKLM,"SOFTWARE\Microsoft\Active Setup\Installed Components\{de5aed00-a4bf-11d1-9948-00c04f98bbc9}","ComponentID",2,"HTMLHelp" diff --git a/reactos/boot/bootdata/hivesys.inf b/reactos/boot/bootdata/hivesys.inf index 5993f16c2ed..9c198fe5c33 100644 --- a/reactos/boot/bootdata/hivesys.inf +++ b/reactos/boot/bootdata/hivesys.inf @@ -1997,6 +1997,18 @@ HKLM,"SYSTEM\CurrentControlSet\Services\MSIServer","ObjectName",0x00000000,"Loca HKLM,"SYSTEM\CurrentControlSet\Services\MSIServer","Start",0x00010001,0x00000003 HKLM,"SYSTEM\CurrentControlSet\Services\MSIServer","Type",0x00010001,0x00000020 +; WMI Service +HKLM,"SYSTEM\CurrentControlSet\Services\winmgmt","DependOnService",0x00010000,"RPCSS" +HKLM,"SYSTEM\CurrentControlSet\Services\winmgmt","DisplayName",0x00000000,"ReactOS Management Infrastructure" +HKLM,"SYSTEM\CurrentControlSet\Services\winmgmt","Description",0x00000000,"Provides interface to system management information" +HKLM,"SYSTEM\CurrentControlSet\Services\winmgmt","ErrorControl",0x00010001,0x00000001 +HKLM,"SYSTEM\CurrentControlSet\Services\winmgmt","Group",0x00000000,"WMI" +HKLM,"SYSTEM\CurrentControlSet\Services\winmgmt","ImagePath",0x00020000,"%SystemRoot%\system32\svchost.exe -k netsvcs" +HKLM,"SYSTEM\CurrentControlSet\Services\winmgmt","ObjectName",0x00000000,"LocalSystem" +HKLM,"SYSTEM\CurrentControlSet\Services\winmgmt","Start",0x00010001,0x00000002 +HKLM,"SYSTEM\CurrentControlSet\Services\winmgmt","Type",0x00010001,0x00000020 +HKLM,"SYSTEM\CurrentControlSet\Services\winmgmt\Parameters","ServiceDll",0x00020000,"%SystemRoot%\system32\wbem\wmisvc.dll" + ; Sound Blaster (NT4) ;HKLM,"SYSTEM\CurrentControlSet\Services\sndblst","Description",0x00000000,"Sound Blaster (NT4)" ;HKLM,"SYSTEM\CurrentControlSet\Services\sndblst","ErrorControl",0x00010001,0x00000001 diff --git a/reactos/dll/win32/CMakeLists.txt b/reactos/dll/win32/CMakeLists.txt index b18f76e65b8..54621f96a15 100644 --- a/reactos/dll/win32/CMakeLists.txt +++ b/reactos/dll/win32/CMakeLists.txt @@ -42,6 +42,7 @@ add_subdirectory(faultrep) add_subdirectory(fltlib) add_subdirectory(fmifs) add_subdirectory(fontsub) +add_subdirectory(framedyn) add_subdirectory(fusion) add_subdirectory(gdiplus) add_subdirectory(getuname) @@ -219,6 +220,8 @@ add_subdirectory(uxtheme) add_subdirectory(vbscript) add_subdirectory(version) add_subdirectory(vssapi) +add_subdirectory(wbemdisp) +add_subdirectory(wbemprox) if(ARCH STREQUAL "i386") add_subdirectory(wdmaud.drv) endif() @@ -235,6 +238,8 @@ add_subdirectory(winsta) add_subdirectory(wintrust) add_subdirectory(wlanapi) add_subdirectory(wldap32) +add_subdirectory(wmi) +add_subdirectory(wmiutils) add_subdirectory(wmvcore) add_subdirectory(ws2_32) add_subdirectory(ws2help) diff --git a/reactos/dll/win32/framedyn/CMakeLists.txt b/reactos/dll/win32/framedyn/CMakeLists.txt new file mode 100644 index 00000000000..74a083df6fa --- /dev/null +++ b/reactos/dll/win32/framedyn/CMakeLists.txt @@ -0,0 +1,24 @@ + +set_cpp(WITH_RUNTIME WITH_EXCEPTIONS) +spec2def(framedyn.dll framedyn.spec ADD_IMPORTLIB) + +list(APPEND SOURCE + main.c + chstring.cpp + provider.cpp + ${CMAKE_CURRENT_BINARY_DIR}/framedyn.def) + +if(MSVC) + add_compile_flags("/Zc:wchar_t-") +endif() + +add_library(framedyn SHARED ${SOURCE}) +set_module_type(framedyn win32dll UNICODE) +add_importlibs(framedyn oleaut32 msvcrt kernel32 ntdll) +add_cd_file(TARGET framedyn DESTINATION reactos/system32/wbem FOR all) + +if(NOT MSVC) + add_asm_files(framedynex_asm alias_gcc.s) + add_library(framedynex ${framedynex_asm}) + set_target_properties(framedynex PROPERTIES LINKER_LANGUAGE ASM) +endif() diff --git a/reactos/dll/win32/framedyn/alias_gcc.s b/reactos/dll/win32/framedyn/alias_gcc.s new file mode 100644 index 00000000000..b71d1baeaa4 --- /dev/null +++ b/reactos/dll/win32/framedyn/alias_gcc.s @@ -0,0 +1,98 @@ +#include + +.code64 +.align 4 + +MACRO(DEFINE_ALIAS, alias, alias2, origstring) +PUBLIC alias +.weakref alias2, origstring +alias: + jmp alias2 +ENDM + +#define DEFINE_ALIAS(alias, orig) DEFINE_ALIAS alias, __wrap_ ## alias, #orig + +DEFINE_ALIAS(__ZN8CHString16AllocBeforeWriteEi, ?AllocBeforeWrite@CHString@@IAEXH@Z) +DEFINE_ALIAS(__ZN8CHString11AllocBufferEi, ?AllocBuffer@CHString@@IAEXH@Z) +DEFINE_ALIAS(__ZNK8CHString9AllocCopyERS_iii, ?AllocCopy@CHString@@IBEXAAV1@HHH@Z) +DEFINE_ALIAS(__ZNK8CHString14AllocSysStringEv, ?AllocSysString@CHString@@QBEPAGXZ) +DEFINE_ALIAS(__ZN8CHString10AssignCopyEiPKw, ?AssignCopy@CHString@@IAEXHPBG@Z) +DEFINE_ALIAS(__ZN8CHStringC1ERKS_, ??0CHString@@QAE@ABV0@@Z) +DEFINE_ALIAS(__ZN8CHStringC1EPKc, ??0CHString@@QAE@PBD@Z) +DEFINE_ALIAS(__ZN8CHStringC1EPKh, ??0CHString@@QAE@PBE@Z) +DEFINE_ALIAS(__ZN8CHStringC1EPKw, ??0CHString@@QAE@PBG@Z) +DEFINE_ALIAS(__ZN8CHStringC1EPKwi, ??0CHString@@QAE@PBGH@Z) +DEFINE_ALIAS(__ZN8CHStringC1Ewi, ??0CHString@@QAE@GH@Z) +DEFINE_ALIAS(__ZN8CHStringC1Ev, ??0CHString@@QAE@XZ) +DEFINE_ALIAS(__ZN8CHStringC2Ev, ??0CHString@@QAE@XZ) // CHString::CHString(void) +DEFINE_ALIAS(__ZNK8CHString7CollateEPKw, ?Collate@CHString@@QBEHPBG@Z) +DEFINE_ALIAS(__ZNK8CHString7CompareEPKw, ?Compare@CHString@@QBEHPBG@Z) +DEFINE_ALIAS(__ZNK8CHString13CompareNoCaseEPKw, ?CompareNoCase@CHString@@QBEHPBG@Z) +DEFINE_ALIAS(__ZN8CHString10ConcatCopyEiPKwiS1_, ?ConcatCopy@CHString@@IAEXHPBGH0@Z) +DEFINE_ALIAS(__ZN8CHString13ConcatInPlaceEiPKw, ?ConcatInPlace@CHString@@IAEXHPBG@Z) +DEFINE_ALIAS(__ZN8CHString15CopyBeforeWriteEv, ?CopyBeforeWrite@CHString@@IAEXXZ) +DEFINE_ALIAS(__ZN8CHString5EmptyEv, ?Empty@CHString@@QAEXXZ) +DEFINE_ALIAS(__ZNK8CHString4FindEPKw, ?Find@CHString@@QBEHPBG@Z) +DEFINE_ALIAS(__ZNK8CHString4FindEw, ?Find@CHString@@QBEHG@Z) +DEFINE_ALIAS(__ZNK8CHString9FindOneOfEPKw, ?FindOneOf@CHString@@QBEHPBG@Z) +DEFINE_ALIAS(__ZN8CHString6FormatEjz, ?Format@CHString@@QAAXIZZ) +DEFINE_ALIAS(__ZN8CHString6FormatEPKwz, ?Format@CHString@@QAAXPBGZZ) +DEFINE_ALIAS(__ZN8CHString14FormatMessageWEjz, ?FormatMessageW@CHString@@QAAXIZZ) +DEFINE_ALIAS(__ZN8CHString14FormatMessageWEPKwz, ?FormatMessageW@CHString@@QAAXPBGZZ) +DEFINE_ALIAS(__ZN8CHString7FormatVEPKwPc, ?FormatV@CHString@@QAEXPBGPAD@Z) +DEFINE_ALIAS(__ZN8CHString9FreeExtraEv, ?FreeExtra@CHString@@QAEXXZ) +DEFINE_ALIAS(__ZNK8CHString14GetAllocLengthEv, ?GetAllocLength@CHString@@QBEHXZ) +DEFINE_ALIAS(__ZNK8CHString5GetAtEi, ?GetAt@CHString@@QBEGH@Z) +DEFINE_ALIAS(__ZN8CHString9GetBufferEi, ?GetBuffer@CHString@@QAEPAGH@Z) +DEFINE_ALIAS(__ZN8CHString18GetBufferSetLengthEi, ?GetBufferSetLength@CHString@@QAEPAGH@Z) +DEFINE_ALIAS(__ZNK8CHString7GetDataEv, ?GetData@CHString@@IBEPAUCHStringData@@XZ) +DEFINE_ALIAS(__ZNK8CHString9GetLengthEv, ?GetLength@CHString@@QBEHXZ) +DEFINE_ALIAS(__ZN8CHString4InitEv, ?Init@CHString@@IAEXXZ) +DEFINE_ALIAS(__ZNK8CHString7IsEmptyEv, ?IsEmpty@CHString@@QBEHXZ) +DEFINE_ALIAS(__ZNK8CHString4LeftEi, ?Left@CHString@@QBE?AV1@H@Z) +DEFINE_ALIAS(__ZN8CHString11LoadStringWEj, ?LoadStringW@CHString@@QAEHI@Z) +DEFINE_ALIAS(__ZN8CHString11LoadStringWEjPwj, ?LoadStringW@CHString@@IAEHIPAGI@Z) +DEFINE_ALIAS(__ZN8CHString10LockBufferEv, ?LockBuffer@CHString@@QAEPAGXZ) +DEFINE_ALIAS(__ZN8CHString9MakeLowerEv, ?MakeLower@CHString@@QAEXXZ) +DEFINE_ALIAS(__ZN8CHString11MakeReverseEv, ?MakeReverse@CHString@@QAEXXZ) +DEFINE_ALIAS(__ZN8CHString9MakeUpperEv, ?MakeUpper@CHString@@QAEXXZ) +DEFINE_ALIAS(__ZNK8CHString3MidEi, ?Mid@CHString@@QBE?AV1@H@Z) +DEFINE_ALIAS(__ZNK8CHString3MidEii, ?Mid@CHString@@QBE?AV1@HH@Z) +DEFINE_ALIAS(__ZN8CHString7ReleaseEP12CHStringData@4, ?Release@CHString@@KGXPAUCHStringData@@@Z) +DEFINE_ALIAS(__ZN8CHString7ReleaseEv, ?Release@CHString@@IAEXXZ) +DEFINE_ALIAS(__ZN8CHString13ReleaseBufferEi, ?ReleaseBuffer@CHString@@QAEXH@Z) +DEFINE_ALIAS(__ZNK8CHString11ReverseFindEw, ?ReverseFind@CHString@@QBEHG@Z) +DEFINE_ALIAS(__ZNK8CHString5RightEi, ?Right@CHString@@QBE?AV1@H@Z) +DEFINE_ALIAS(__ZN8CHString10SafeStrlenEPKw@4, ?SafeStrlen@CHString@@KGHPBG@Z) +DEFINE_ALIAS(__ZN8CHString5SetAtEiw, ?SetAt@CHString@@QAEXHG@Z) +DEFINE_ALIAS(__ZNK8CHString13SpanExcludingEPKw, ?SpanExcluding@CHString@@QBE?AV1@PBG@Z) +DEFINE_ALIAS(__ZNK8CHString13SpanIncludingEPKw, ?SpanIncluding@CHString@@QBE?AV1@PBG@Z) +DEFINE_ALIAS(__ZN8CHString8TrimLeftEv, ?TrimLeft@CHString@@QAEXXZ) +DEFINE_ALIAS(__ZN8CHString9TrimRightEv, ?TrimRight@CHString@@QAEXXZ) +DEFINE_ALIAS(__ZN8CHString12UnlockBufferEv, ?UnlockBuffer@CHString@@QAEXXZ) +DEFINE_ALIAS(__ZNK8CHStringcvPKwEv, ??BCHString@@QBEPBGXZ) +DEFINE_ALIAS(__ZN8CHStringpLERKS_, ??YCHString@@QAEABV0@ABV0@@Z) +DEFINE_ALIAS(__ZN8CHStringpLEc, ??YCHString@@QAEABV0@D@Z) +DEFINE_ALIAS(__ZN8CHStringpLEPKw, ??YCHString@@QAEABV0@PBG@Z) +DEFINE_ALIAS(__ZN8CHStringpLEw, ??YCHString@@QAEABV0@G@Z) +DEFINE_ALIAS(__ZN8CHStringaSEPS_, ??4CHString@@QAEABV0@PAV0@@Z) +DEFINE_ALIAS(__ZN8CHStringaSERKS_, ??4CHString@@QAEABV0@ABV0@@Z) +DEFINE_ALIAS(__ZN8CHStringaSEPKc, ??4CHString@@QAEABV0@PBD@Z) +DEFINE_ALIAS(__ZN8CHStringaSEc, ??4CHString@@QAEABV0@D@Z) +DEFINE_ALIAS(__ZN8CHStringaSEPKh, ??4CHString@@QAEABV0@PBE@Z) +DEFINE_ALIAS(__ZN8CHStringaSEPKw, ??4CHString@@QAEABV0@PBG@Z) +DEFINE_ALIAS(__ZN8CHStringaSEw, ??4CHString@@QAEABV0@G@Z) +DEFINE_ALIAS(__ZNK8CHStringixEi, ??ACHString@@QBEGH@Z) +DEFINE_ALIAS(__ZN8CHStringD1Ev, ??1CHString@@QAE@XZ) // CHString::~CHString() complete object destructor +DEFINE_ALIAS(__ZN8CHStringD2Ev, ??1CHString@@QAE@XZ) // CHString::~CHString() base object destructor +DEFINE_ALIAS(__ZplwRK8CHString, ??H@YG?AVCHString@@GABV0@@Z) +DEFINE_ALIAS(__ZplRK8CHStringw, ??H@YG?AVCHString@@ABV0@G@Z) +DEFINE_ALIAS(__ZplRK8CHStringPKw, ??H@YG?AVCHString@@ABV0@PBG@Z) +DEFINE_ALIAS(__ZplPKwRK8CHString, ??H@YG?AVCHString@@PBGABV0@@Z) +DEFINE_ALIAS(__ZplRK8CHStringS1_, ??H@YG?AVCHString@@ABV0@0@Z) +DEFINE_ALIAS(__ZN8Provider5FlushEv, ?Flush@Provider@@MAEXXZ) +DEFINE_ALIAS(__ZN8Provider21ValidateDeletionFlagsEl, ?ValidateDeletionFlags@Provider@@MAEJJ@Z) +DEFINE_ALIAS(__ZN8Provider19ValidateMethodFlagsEl, ?ValidateMethodFlags@Provider@@MAEJJ@Z) +DEFINE_ALIAS(__ZN8Provider18ValidateQueryFlagsEl, ?ValidateQueryFlags@Provider@@MAEJJ@Z) + +END diff --git a/reactos/dll/win32/framedyn/chstring.cpp b/reactos/dll/win32/framedyn/chstring.cpp new file mode 100644 index 00000000000..f8779c0b277 --- /dev/null +++ b/reactos/dll/win32/framedyn/chstring.cpp @@ -0,0 +1,1404 @@ +/* + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS system libraries + * FILE: dll/win32/framedyn/chstring.cpp + * PURPOSE: CHString class implementation + * PROGRAMMERS: Pierre Schweitzer (pierre@reactos.org) + * + * NOTE: This implementation is BROKEN on PURPOSE + * The CHString is a mix between std::string and + * UNICODE_STRING. It appears that basically it takes only + * the worse from both approaches. + * I've copied the behavior and implementation of Windows 2k3 even if + * it implies unsafe, wrong or unefficient methods. + * Note that the string at m_pchData might not be null terminated! + * Also, important note, two (or even more) CHString instances might + * have the same m_pchData object! Never forget that while modifying + * a string. You might be modifying the string for everyone. + * This is why a protected method is being used in the code: CopyBeforeWrite + * It copies source first, to ensure we only modify current string + * Side note, all the sizes are actually a number of chars. Only the size + * for implementation is the number of bytes + * Now, you know why this class is deprecated and shouldn't be used + */ + +/* INCLUDES ******************************************************************/ + +#include +#define NDEBUG +#include + +/* PRIVATE FUNCTIONS *********************************************************/ + +// This is the empty string that defaults strings without text +// This is unsafe. This string show be LPCWSTR +// However we have to assign it to LPWSTR var. So, let's ignore about const, +// as MS does. Normally we check in our code that we don't overwrite this string. +LPWSTR afxPchNil = (LPWSTR)L"\0"; +// This is the data that are matching the null string upper +CHStringData afxNullData = {0, 0, 0}; +// Exception we may throw in case of allocation failure +CHeap_Exception HeapException(CHeap_Exception::E_ALLOCATION_ERROR); + +// Our own delete operator +// It is here basically because MS guys don't known about set_new_handler() +// See operator new +void operator delete(void* ptr) +{ + // In Windows 2k3, they check for ptr being null. + // ISO, POSIX and even MSDN explains that it is allowed + // to call free with NULL pointer... + if (ptr) + { + free(ptr); + } +} + +// Implement our own new operator so that we can throw our own exception in case +// of allocation failure. +// It could have been done using set_new_handler(), but well. MS guys didn't do it +// that way. So, let's mimic. +void* operator new(size_t uSize) +{ + void* Buffer; + + Buffer = malloc(uSize); + if (!Buffer) + { + throw HeapException; + } + + return Buffer; +} + +// This is a char to wchar string conversion helper +int mbstowcsz(LPWSTR lpDest, LPCSTR lpSrc, int nLen) +{ + int Conv; + + // If we have nothing to convert or if output doesn't exist, return + if (nLen == 0 || lpDest == 0) + { + return 0; + } + + // Then, simply convert + Conv = MultiByteToWideChar(CP_ACP, 0, lpSrc, -1, lpDest, nLen); + // In case of conversion success, null terminate the string + if (Conv != 0) + { + lpDest[nLen] = 0; + } + + return Conv; +} + +/* PUBLIC FUNCTIONS **********************************************************/ + +/* + * @implemented + */ +CHString::CHString() +{ + // Set to empty string + m_pchData = afxPchNil; +} + +/* + * @implemented + */ +CHString::CHString(WCHAR ch, int nRepeat) throw (CHeap_Exception) +{ + // Allow null initialize, in case something goes wrong + m_pchData = afxPchNil; + + // If we have a char to insert + if (nRepeat >= 1) + { + // Allocate a buffer big enough + AllocBuffer(nRepeat); + // And if possible, repeat char + if (m_pchData) + { + for (int i = 0; i < nRepeat; ++i) + { + m_pchData[i] = ch; + } + } + } +} + +/* + * @implemented + */ +CHString::CHString(LPCWSTR lpsz) throw (CHeap_Exception) +{ + // Allow null initialize, in case something goes wrong + m_pchData = afxPchNil; + + // If we have an input string + if (lpsz != 0) + { + // Get its length + int Len = SafeStrlen(lpsz); + // Then, allocate a big enough buffer and copy string + // Note that here, we don't null terminate the string... + if (Len) + { + AllocBuffer(Len); + wcsncpy(m_pchData, lpsz, Len); + } + } +} + +/* + * @implemented + */ +CHString::CHString(LPCWSTR lpch, int nLength) throw (CHeap_Exception) +{ + // Allow null initialize, in case something goes wrong + m_pchData = afxPchNil; + + // In case we have a string with a len + if (lpch != 0 && nLength != 0) + { + // Just copy the string + AllocBuffer(nLength); + wcsncpy(m_pchData, lpch, nLength); + } +} + +/* + * @implemented + */ +CHString::CHString(LPCSTR lpsz) throw (CHeap_Exception) +{ + // Allow null initialize, in case something goes wrong + m_pchData = afxPchNil; + + // If we have input string + if (lpsz != 0) + { + // Get its length + int Len = (int)strlen(lpsz); + if (Len) + { + // Allocate and convert the string + AllocBuffer(Len); + mbstowcsz(m_pchData, lpsz, Len + 1); + // Releasing buffer here is to allow to + // update the buffer size. We notify we're + // done with changing the string: recompute its + // length, please + ReleaseBuffer(); + } + } +} + +/* + * @implemented + */ +CHString::CHString(const unsigned char* lpsz) +{ + // Null init + Init(); + // And call operator= with const char*, easier + *this = (LPCSTR)lpsz; +} + +/* + * @implemented + */ +CHString::CHString(const CHString& stringSrc) +{ + // If we have currently no referenced string + if (stringSrc.GetData()->nRefs < 0) + { + // Ensure we have the null string + m_pchData = afxPchNil; + // And then call, the copy operator with input string + *this = stringSrc.m_pchData; + } + else + { + // Otherwise, just copy the input string + m_pchData = stringSrc.m_pchData; + // And increment the number of references + InterlockedIncrement(&GetData()->nRefs); + // The whole point here is: Am I forget to release the old + // data?! MS doesn't release it, but I guess we should... + } +} + +/* + * @implemented + */ +CHString::~CHString() +{ + // If we have a string + if (GetData() != &afxNullData) + { + // Check whether it's still in use after we release it + if (InterlockedDecrement(&GetData()->nRefs) == 0) + { + // If so, delete it + delete GetData(); + } + } +} + +/* + * @implemented + */ +void CHString::AllocBeforeWrite(int nLen) throw (CHeap_Exception) +{ + // In case we have several strings pointing to our memory zone + // Or we need bigger buffer than actual + if (GetData()->nRefs > 1 || nLen > GetData()->nAllocLength) + { + // Just drop current + // And allocate a new one which is big enough + Release(); + AllocBuffer(nLen); + } +} + +/* + * @implemented + */ +void CHString::AllocBuffer(int nSize) throw (CHeap_Exception) +{ + // Here we have to allocate a buffer for the string + // It actually consists in: CHStringData structure + // with a buffer big enough at its end to store the + // string. + CHStringData* Data; + + // Null size is easy allocation + if (nSize == 0) + { + m_pchData = afxPchNil; + return; + } + + // We cannot allow negative sizes + if (nSize < 0) + { + RaiseException(ERROR_INVALID_PARAMETER, EXCEPTION_NONCONTINUABLE, 0, 0); + } + + // Nor too big + if (nSize > (INT_MAX - (int)sizeof(CHStringData)) / (int)sizeof(WCHAR)) + { + RaiseException(STATUS_INTEGER_OVERFLOW, EXCEPTION_NONCONTINUABLE, 0, 0); + } + + // Just allocate big enough buffer, using our own operator new + Data = (CHStringData *)operator new(nSize * sizeof(WCHAR) + sizeof(CHStringData)); + // In case Data is null, throw an exception + // Yes, this is stupid! Our operator new is already supposed to through an exception... + // Thanks MS + if (!Data) + { + throw HeapException; + } + + Data->nRefs = 1; + Data->nDataLength = nSize; + Data->nAllocLength = nSize; + Data->data()[0] = 0; + + // We only return the string + // We can find back data with some mathematics + m_pchData = Data->data(); +} + +/* + * @implemented + */ +void CHString::AllocCopy(CHString& dest, int nCopyLen, int nCopyIndex, int nExtraLen) const throw (CHeap_Exception) +{ + // Once again, we cannot deal with negative lens + if (nCopyLen < 0) + { + RaiseException(ERROR_INVALID_PARAMETER, EXCEPTION_NONCONTINUABLE, 0, 0); + } + + if (nCopyIndex < 0) + { + RaiseException(ERROR_INVALID_PARAMETER, EXCEPTION_NONCONTINUABLE, 0, 0); + } + + if (nExtraLen < 0) + { + RaiseException(ERROR_INVALID_PARAMETER, EXCEPTION_NONCONTINUABLE, 0, 0); + } + + // In case what we have to copy is null-sized, just set empty string + if (nCopyLen + nExtraLen == 0) + { + dest.m_pchData = afxPchNil; + return; + } + + // Otherwise, allocate a buffer in new string which is big enough + // You can note that we absolutely don't check about any existing + // (referenced) buffer in dest. Actually, dest is to be EMPTY string. + // The whole point of this function is to initialize a virgin string by + // copying data from another. This is needed by Left/Mid/Right + dest.AllocBuffer(nCopyLen + nExtraLen); + // And copy our stuff in + wcsncpy(dest.m_pchData, m_pchData + nCopyIndex, nCopyLen); +} + +/* + * @implemented + */ +BSTR CHString::AllocSysString() const throw (CHeap_Exception) +{ + BSTR SysString; + + // Just allocate the string + SysString = SysAllocStringLen(m_pchData, GetData()->nDataLength); + if (!SysString) + { + throw HeapException; + } + + return SysString; +} + +/* + * @implemented + */ +void CHString::AssignCopy(int nSrcLen, LPCWSTR lpszSrcData) throw (CHeap_Exception) +{ + // Don't allow negative len + if (nSrcLen < 0) + { + RaiseException(ERROR_INVALID_PARAMETER, EXCEPTION_NONCONTINUABLE, 0, 0); + } + + // We will have to modify a string that might be shared, so duplicate it + // Ensuring it's big enough to contain our new stuff + AllocBeforeWrite(nSrcLen); + if (nSrcLen == 0) + { + Release(); + return; + } + + // Just copy, write down new size, and ensure it's null terminated + wcsncpy(m_pchData, lpszSrcData, nSrcLen); + GetData()->nDataLength = nSrcLen; + m_pchData[nSrcLen] = 0; +} + +/* + * @implemented + */ +int CHString::Collate(LPCWSTR lpsz) const +{ + // Just call the deprecated function here - no matter we are null terminated + // Did you read my statement about how safe is this implementation? + return wcscoll(m_pchData, lpsz); +} + +/* + * @implemented + */ +int CHString::Compare(LPCWSTR lpsz) const +{ + // Just call the deprecated function here - no matter we are null terminated + // Did you read my statement about how safe is this implementation? + return wcscmp(m_pchData, lpsz); +} + +/* + * @implemented + */ +int CHString::CompareNoCase(LPCWSTR lpsz) const +{ + // Just call the deprecated function here - no matter we are null terminated + // Did you read my statement about how safe is this implementation? + return wcsicmp(m_pchData, lpsz); +} + +/* + * @implemented + */ +void CHString::ConcatInPlace(int nSrcLen, LPCWSTR lpszSrcData) +{ + // With null length, there's not that much to concat... + if (nSrcLen == 0) + { + return; + } + + // Still no negative length + if (nSrcLen < 0) + { + RaiseException(ERROR_INVALID_PARAMETER, EXCEPTION_NONCONTINUABLE, 0, 0); + } + + // Ensure we wouldn't overflow with the concat + if (GetData()->nDataLength > INT_MAX - nSrcLen) + { + RaiseException(STATUS_INTEGER_OVERFLOW, EXCEPTION_NONCONTINUABLE, 0, 0); + } + + // In case we have to modify a shared string OR if it can't fit into current buffer... + if (GetData()->nRefs > 1 || GetData()->nDataLength + nSrcLen > GetData()->nAllocLength) + { + // Allocate a new buffer! (without forgetting to release old one) + CHStringData* OldData = GetData(); + + // You remember about "InPlace" in the function's name? + // The cake is a lie + ConcatCopy(GetData()->nDataLength, m_pchData, nSrcLen, lpszSrcData); + Release(OldData); + } + else + { + // Ensure we don't overflow + if (nSrcLen > INT_MAX - GetData()->nDataLength) + { + RaiseException(STATUS_INTEGER_OVERFLOW, EXCEPTION_NONCONTINUABLE, 0, 0); + } + + // Then, just copy and null terminate + wcsncpy(m_pchData + GetData()->nDataLength, lpszSrcData, nSrcLen); + GetData()->nDataLength += nSrcLen; + m_pchData[GetData()->nDataLength] = 0; + } +} + +/* + * @implemented + */ +void CHString::ConcatCopy(int nSrc1Len, LPCWSTR lpszSrc1Data, int nSrc2Len, LPCWSTR lpszSrc2Data) throw (CHeap_Exception) +{ + int TotalLen; + + if (nSrc1Len < 0 || nSrc2Len < 0) + { + RaiseException(ERROR_INVALID_PARAMETER, EXCEPTION_NONCONTINUABLE, 0, 0); + } + + // If both len are null, do nothing + TotalLen = nSrc1Len + nSrc2Len; + if (TotalLen == 0) + { + return; + } + + // Otherwise, allocate a new buffer to hold everything (caller will release previous buffer) + AllocBuffer(TotalLen); + // And concat stuff + wcsncpy(m_pchData, lpszSrc1Data, nSrc1Len); + wcsncpy(m_pchData + nSrc1Len, lpszSrc2Data, nSrc2Len); +} + +/* + * @implemented + */ +void CHString::CopyBeforeWrite() throw (CHeap_Exception) +{ + CHStringData* Data; + + // First, we need to get reference count + // And we also need to save Data for later copy + Data = GetData(); + + if (Data->nRefs <= 1) + { + // If its not used, don't waste time to realloc, it will do the job + return; + } + + // Release current data - we are sure it won't be freed upon that point + // Thanks to the reference count check previously done + Release(); + // Alloc new buffer and copy old data in it + AllocBuffer(Data->nDataLength); + wcsncpy(m_pchData, Data->data(), Data->nDataLength); +} + +/* + * @implemented + */ +void CHString::Empty() +{ + // Already empty + if (GetData()->nDataLength == 0) + { + return; + } + + // Empty it easily given it's reference count + if (GetData()->nRefs < 0) + { + *this = afxPchNil; + } + else + { + // Otherwise, just release it + // It will set back this instance to afxPchNil + // while decreasing reference count + Release(); + } +} + +/* + * @implemented + */ +int CHString::Find(WCHAR ch) const +{ + WCHAR *Found; + + // Let's use appropriate helper + Found = wcschr(m_pchData, ch); + // We have to return a position, so compute it + if (Found) + { + return (Found - m_pchData); + } + + // Otherwise, return no position + return -1; +} + +/* + * @implemented + */ +int CHString::Find(LPCWSTR lpszSub) const +{ + WCHAR *Found; + + // Let's use appropriate helper + Found = wcsstr(m_pchData, lpszSub); + // We have to return a position, so compute it + if (Found) + { + return (Found - m_pchData); + } + + // Otherwise, return no position + return -1; +} + +/* + * @implemented + */ +int CHString::FindOneOf(LPCWSTR lpszCharSet) const +{ + WCHAR *Found; + + // Let's use appropriate helper + Found = wcspbrk(m_pchData, lpszCharSet); + // We have to return a position, so compute it + if (Found) + { + return (Found - m_pchData); + } + + // Otherwise, return no position + return -1; +} + +/* + * @implemented + */ +void CHString::Format(UINT nFormatID, ...) throw (CHeap_Exception) +{ + // Deprecated and not implemented any longer - well, this is its implementation + return; +} + +/* + * @implemented + */ +void CHString::Format(LPCWSTR lpszFormat, ...) throw (CHeap_Exception) +{ + // Forward to FormatV + va_list ArgsList; + + va_start(ArgsList, lpszFormat); + FormatV(lpszFormat, ArgsList); + va_end(ArgsList); +} + +/* + * @implemented + */ +void CHString::FormatMessageW(UINT nFormatID, ...) throw (CHeap_Exception) +{ + // Deprecated and not implemented any longer - well, this is its implementation + return; +} + +/* + * @unimplemented + */ +void CHString::FormatMessageW(LPCWSTR lpszFormat, ...) throw (CHeap_Exception) +{ + UNIMPLEMENTED; +} + +/* + * @unimplemented + */ +void CHString::FormatV(LPCWSTR lpszFormat, va_list argList) +{ + UNIMPLEMENTED; +} + +/* + * @implemented + */ +void CHString::FreeExtra() throw (CHeap_Exception) +{ + CHStringData* OldData; + + // No extra? Do nothing + if (GetData()->nDataLength == GetData()->nAllocLength) + { + return; + } + + // Get old buffer + OldData = GetData(); + // Allocate a new one, at the right size (with no place for \0 :-)) + AllocBuffer(GetData()->nDataLength); + // Copy old and release it + wcsncpy(m_pchData, OldData->data(), OldData->nDataLength); + Release(OldData); +} + +/* + * @implemented + */ +int CHString::GetAllocLength() const +{ + return GetData()->nAllocLength; +} + +/* + * @implemented + */ +WCHAR CHString::GetAt(int nIndex) const +{ + // It's up to you to check the index! + return m_pchData[nIndex]; +} + +/* + * @implemented + */ +LPWSTR CHString::GetBuffer(int nMinBufLength) throw (CHeap_Exception) +{ + LPWSTR OldBuffer = m_pchData; + + // We'll have to allocate a new buffer if it's not big enough + // or if it's shared by several strings + if (GetData()->nRefs > 1 || GetData()->nAllocLength < nMinBufLength) + { + CHStringData* OldData = GetData(); + int OldLen = GetData()->nDataLength; + + // Ensure we can hold enough + if (OldLen > nMinBufLength) + { + nMinBufLength = OldLen; + } + + // Allocate new buffer + AllocBuffer(nMinBufLength); + // Copy contents + wcsncpy(m_pchData, OldBuffer, OldLen); + GetData()->nDataLength = OldLen; + + // Release old + Release(OldData); + } + + // Weirdly, here Windows always returns the old buffer + // Which basically exposes a wrong buffer + return OldBuffer; +} + +/* + * @implemented + */ +LPWSTR CHString::GetBufferSetLength(int nNewLength) throw (CHeap_Exception) +{ + // Get a buffer big enough + // We don't care about the return, it will be set in the string + (void)GetBuffer(nNewLength); + // Set length, null-terminate and return + GetData()->nDataLength = nNewLength; + m_pchData[nNewLength] = 0; + return m_pchData; +} + +/* + * @implemented + */ +CHStringData* CHString::GetData() const +{ + // In case of empty string, return empty data + if (m_pchData == afxPchNil) + { + return &afxNullData; + } + + // Otherwise, do maths + return (CHStringData*)((ULONG_PTR)m_pchData - sizeof(CHStringData)); +} + +/* + * @implemented + */ +int CHString::GetLength() const +{ + return GetData()->nDataLength; +} + +/* + * @implemented + */ +void CHString::Init() +{ + m_pchData = afxPchNil; +} + +/* + * @implemented + */ +BOOL CHString::IsEmpty() const +{ + return (GetData()->nDataLength == 0); +} + +/* + * @implemented + */ +CHString CHString::Left(int nCount) const throw (CHeap_Exception) +{ + CHString NewString; + + // Validate input (we can't get more than what we have ;-)) + if (nCount) + { + if (nCount > GetData()->nDataLength) + { + nCount = GetData()->nDataLength; + } + } + + AllocCopy(NewString, nCount, 0, 0); + + return NewString; +} + +/* + * @implemented + */ +int CHString::LoadStringW(UINT nID) throw (CHeap_Exception) +{ + // Deprecated and not implemented any longer - well, this is its implementation + return 0; +} + +/* + * @implemented + */ +int CHString::LoadStringW(UINT nID, LPWSTR lpszBuf, UINT nMaxBuf) throw (CHeap_Exception) +{ + // Deprecated and not implemented any longer - well, this is its implementation + return 0; +} + +/* + * @implemented + */ +LPWSTR CHString::LockBuffer() +{ + LPWSTR LockedBuffer; + + // The purpose here is basically to set the nRefs to max int + LockedBuffer = GetBuffer(0); + GetData()->nRefs = INT_MAX; + + return LockedBuffer; +} + +/* + * @implemented + */ +void CHString::MakeLower() throw (CHeap_Exception) +{ + // We'll modify string, duplicate it first if needed + CopyBeforeWrite(); + + // Let's use appropriate helper + _wcslwr(m_pchData); +} + +/* + * @implemented + */ +void CHString::MakeReverse() throw (CHeap_Exception) +{ + // We'll modify string, duplicate it first if needed + CopyBeforeWrite(); + + // Let's use appropriate helper + _wcsrev(m_pchData); +} + +/* + * @implemented + */ +void CHString::MakeUpper() throw (CHeap_Exception) +{ + // We'll modify string, duplicate it first if needed + CopyBeforeWrite(); + + // Let's use appropriate helper + _wcsupr(m_pchData); +} + +/* + * @implemented + */ +CHString CHString::Mid(int nFirst) const throw (CHeap_Exception) +{ + // Take string from nFirst up to the end + return Mid(nFirst, GetData()->nDataLength - nFirst); +} + +/* + * @implemented + */ +CHString CHString::Mid(int nFirst, int nCount) const throw (CHeap_Exception) +{ + CHString NewString; + + // Validate sizes first + if (nFirst < 0) + { + nFirst = 0; + } + + if (nCount < 0) + { + nCount = 0; + } + + // Ensure we don't go beyond the string + if (nFirst + nCount > GetData()->nDataLength) + { + nCount = GetData()->nDataLength - nFirst; + } + + // Also ensure we don't read beyond + // Yes, this should have been done before previous check + // MS does it that way + if (nFirst > GetData()->nDataLength) + { + nCount = 0; + } + + AllocCopy(NewString, nCount, nFirst, 0); + + return NewString; +} + +/* + * @implemented + */ +void CHString::Release() +{ + // If null string, nothing to do + if (GetData() == &afxNullData) + { + return; + } + + // Otherwise, decrement ref count and release if required + if (InterlockedDecrement(&GetData()->nRefs) == 0) + { + delete GetData(); + } + + // In all cases, caller doesn't want string anymore + // So, switch back to empty string + m_pchData = afxPchNil; +} + +/* + * @implemented + */ +void WINAPI CHString::Release(CHStringData* pData) +{ + // If empty string, ignore + if (pData == &afxNullData) + { + return; + } + + // Otherwise, simply and free if needed + if (InterlockedDecrement(&pData->nRefs) == 0) + { + delete pData; + } +} + +/* + * @implemented + */ +void CHString::ReleaseBuffer(int nNewLength) throw (CHeap_Exception) +{ + CHStringData* Data; + + // We'll modify buffer, so duplicate + CopyBeforeWrite(); + + // If no len provided, get one + if (nNewLength == -1) + { + nNewLength = (int)wcslen(m_pchData); + } + + // Set appropriate size and null-terminate + Data = GetData(); + Data->nDataLength = nNewLength; + Data->data()[nNewLength] = 0; +} + +/* + * @implemented + */ +int CHString::ReverseFind(WCHAR ch) const +{ + WCHAR *Last; + + // Let's use appropriate helper + Last = wcsrchr(m_pchData, ch); + // We have to return a position, so compute it + if (Last) + { + return (Last - m_pchData); + } + + // Otherwise, return no position + return -1; +} + +/* + * @implemented + */ +CHString CHString::Right(int nCount) const throw (CHeap_Exception) +{ + CHString NewString; + + // Validate input (we can't get more than what we have ;-)) + if (nCount >= 0) + { + if (nCount > GetData()->nDataLength) + { + nCount = GetData()->nDataLength; + } + } + + AllocCopy(NewString, nCount, GetData()->nDataLength - nCount, 0); + + return NewString; +} + +/* + * @implemented + */ +int CHString::SafeStrlen(LPCWSTR lpsz) +{ + // Check we have a string and then get its length + if (lpsz == 0) + { + return 0; + } + + // Of course, it's not safe at all in case string is not null-terminated. + // Things that may happen given strings are not to be null-terminated + // in this class... + return (int)wcslen(lpsz); +} + +/* + * @implemented + */ +void CHString::SetAt(int nIndex, WCHAR ch) throw (CHeap_Exception) +{ + CopyBeforeWrite(); + + m_pchData[nIndex] = ch; +} + +/* + * @implemented + */ +CHString CHString::SpanExcluding(LPCWSTR lpszCharSet) const throw (CHeap_Exception) +{ + int Count; + + // Get position and then, extract + Count = (int)wcscspn(m_pchData, lpszCharSet); + return Left(Count); +} + +/* + * @implemented + */ +CHString CHString::SpanIncluding(LPCWSTR lpszCharSet) const throw (CHeap_Exception) +{ + int Count; + + // Get position and then, extract + Count = (int)wcsspn(m_pchData, lpszCharSet); + return Left(Count); +} + +/* + * @implemented + */ +void CHString::TrimLeft() throw (CHeap_Exception) +{ + int NewBegin; + int NewLength; + WCHAR *CurrentChar; + + // We'll modify, so copy first + CopyBeforeWrite(); + + // Start at the begin of the string + CurrentChar = m_pchData; + while (*CurrentChar != 0) + { + // Browse string till we find something which is not a space + if (!iswspace(*CurrentChar)) + { + break; + } + + CurrentChar++; + } + + // Then, calculate new begin (easy) and new length + // And move memory + NewBegin = (CurrentChar - m_pchData); + NewLength = GetData()->nDataLength - NewBegin; + memmove(m_pchData, CurrentChar, NewLength * sizeof(WCHAR)); + GetData()->nDataLength = NewLength; +} + +/* + * @implemented + */ +void CHString::TrimRight() throw (CHeap_Exception) +{ + WCHAR *CurrentChar; + WCHAR *CanBeEaten; + + // We'll modify, so copy first + CopyBeforeWrite(); + + // Start at the begin of the string -- WHAT?! + // Yes, this algorithm is the same that MS is + // using for its TrimRight. + // It is highly unefficient. It would have been + // easier to start at nDataLength and to get back to + // the begin. Note that it would have been safer as + // well, in case the caller is using non-null-terminated + // strings. But, well... + CurrentChar = m_pchData; + CanBeEaten = 0; + while (*CurrentChar != 0) + { + // If not a space, reset what we can trim + if (!iswspace(*CurrentChar)) + { + CanBeEaten = 0; + } + // If it is one, and the first of the spaces serie + // Keep its position + else if (CanBeEaten == 0) + { + CanBeEaten = CurrentChar; + } + + CurrentChar++; + } + + // If nothing to trim, quit + if (CanBeEaten == 0) + { + return; + } + + // Otherwise, shorten the string + GetData()->nDataLength = (CanBeEaten - m_pchData); +} + +/* + * @implemented + */ +void CHString::UnlockBuffer() +{ + // Unlock means just put ref back to 1 + // It was previously set to MAX_INT + if (GetData() != &afxNullData) + { + GetData()->nRefs = 1; + } +} + +/* + * @implemented + */ +const CHString& CHString::operator=(char ch) throw (CHeap_Exception) +{ + *this = (WCHAR)ch; + return *this; +} + +/* + * @implemented + */ +const CHString& CHString::operator=(WCHAR ch) throw (CHeap_Exception) +{ + AssignCopy(1, &ch); + return *this; +} + +/* + * @implemented + */ +const CHString& CHString::operator=(CHString *p) throw (CHeap_Exception) +{ + *this = *p; + return *this; +} + +/* + * @implemented + */ +const CHString& CHString::operator=(LPCSTR lpsz) throw (CHeap_Exception) +{ + int Len; + + // If we have string, get its len + if (lpsz != 0) + { + Len = (int)strlen(lpsz); + } + else + { + Len = 0; + } + + // Do this call, even with null len, just to get empty string + AllocBeforeWrite(Len); + if (Len == 0) + { + Release(); + return *this; + } + + // Convert and copy + mbstowcsz(m_pchData, lpsz, Len + 1); + // Get new size and so on + ReleaseBuffer(); + + return *this; +} + +/* + * @implemented + */ +const CHString& CHString::operator=(LPCWSTR lpsz) throw (CHeap_Exception) +{ + int Len; + + Len = SafeStrlen(lpsz); + AssignCopy(Len, lpsz); + + return *this; +} + +/* + * @implemented + */ +const CHString& CHString::operator=(const CHString& stringSrc) throw (CHeap_Exception) +{ + // Don't copy string on itself + if (&stringSrc == this) + { + return *this; + } + + // In case we don't have a referenced string here, + // or if the other is not referenced, just copy here + if ((GetData()->nRefs < 0 && GetData() != &afxNullData) || + stringSrc.GetData()->nRefs < 0) + { + AssignCopy(stringSrc.GetData()->nDataLength, stringSrc.m_pchData); + return *this; + } + + // Otherwise, release current buffer + Release(); + // And set buffer as stringSrc buffer + // And increase its reference count + m_pchData = stringSrc.m_pchData; + InterlockedIncrement(&GetData()->nRefs); + + return *this; +} + +/* + * @implemented + */ +const CHString& CHString::operator=(const unsigned char* lpsz) throw (CHeap_Exception) +{ + *this = (LPCSTR)lpsz; + return *this; +} + +/* + * @implemented + */ +const CHString& CHString::operator+=(char ch) throw (CHeap_Exception) +{ + *this += (WCHAR)ch; + return *this; +} + +/* + * @implemented + */ +const CHString& CHString::operator+=(WCHAR ch) throw (CHeap_Exception) +{ + ConcatInPlace(1, &ch); + return *this; +} + +/* + * @implemented + */ +const CHString& CHString::operator+=(LPCWSTR lpsz) throw (CHeap_Exception) +{ + int Len; + + Len = SafeStrlen(lpsz); + ConcatInPlace(Len, lpsz); + + return *this; +} + +/* + * @implemented + */ +const CHString& CHString::operator+=(const CHString& string) throw (CHeap_Exception) +{ + ConcatInPlace(string.GetData()->nDataLength, string.m_pchData); + + return *this; +} + +/* + * @implemented + */ +WCHAR CHString::operator[](int nIndex) const +{ + return m_pchData[nIndex]; +} + +/* + * @implemented + */ +CHString::operator LPCWSTR() const +{ + return m_pchData; +} + +/* + * @implemented + */ +CHString WINAPI operator+(WCHAR ch, const CHString& string) throw (CHeap_Exception) +{ + CHString NewString; + + // Basically concat in a new string + NewString.ConcatCopy(1, &ch, string.GetData()->nDataLength, string.m_pchData); + + return NewString; +} + +/* + * @implemented + */ +CHString WINAPI operator+(const CHString& string, WCHAR ch) throw (CHeap_Exception) +{ + CHString NewString; + + // Basically concat in a new string + NewString.ConcatCopy(string.GetData()->nDataLength, string.m_pchData, 1, &ch); + + return NewString; +} + +/* + * @implemented + */ +CHString WINAPI operator+(const CHString& string, LPCWSTR lpsz) throw (CHeap_Exception) +{ + int Len; + CHString NewString; + + // Get string length + Len = CHString::SafeStrlen(lpsz); + // And concat in new string + NewString.ConcatCopy(string.GetData()->nDataLength, string.m_pchData, Len, lpsz); + + return NewString; +} + +/* + * @implemented + */ +CHString WINAPI operator+(LPCWSTR lpsz, const CHString& string) throw (CHeap_Exception) +{ + int Len; + CHString NewString; + + // Get string length + Len = CHString::SafeStrlen(lpsz); + // And concat in new string + NewString.ConcatCopy(Len, lpsz, string.GetData()->nDataLength, string.m_pchData); + + return NewString; +} + +/* + * @implemented + */ +CHString WINAPI operator+(const CHString& string1, const CHString& string2) throw (CHeap_Exception) +{ + CHString NewString; + + // Basically concat in a new string + NewString.ConcatCopy(string1.GetData()->nDataLength, string1.m_pchData, + string2.GetData()->nDataLength, string2.m_pchData); + + return NewString; +} diff --git a/reactos/dll/win32/framedyn/framedyn.spec b/reactos/dll/win32/framedyn/framedyn.spec new file mode 100644 index 00000000000..2e576cec0e4 --- /dev/null +++ b/reactos/dll/win32/framedyn/framedyn.spec @@ -0,0 +1,778 @@ + +# **************** x86 exports **************** +@ thiscall -arch=i386 ?AllocBeforeWrite@CHString@@IAEXH@Z(long) _ZN8CHString16AllocBeforeWriteEi # protected: void __thiscall CHString::AllocBeforeWrite(int) +@ thiscall -arch=i386 ?AllocBuffer@CHString@@IAEXH@Z(long) _ZN8CHString11AllocBufferEi # protected: void __thiscall CHString::AllocBuffer(int) +@ thiscall -arch=i386 ?AllocCopy@CHString@@IBEXAAV1@HHH@Z(ptr long long long) _ZNK8CHString9AllocCopyERS_iii # protected: void __thiscall CHString::AllocCopy(class CHString &,int,int,int)const +@ thiscall -arch=i386 ?AllocSysString@CHString@@QBEPAGXZ() _ZNK8CHString14AllocSysStringEv +@ thiscall -arch=i386 ?AssignCopy@CHString@@IAEXHPBG@Z(long wstr) _ZN8CHString10AssignCopyEiPKw +@ thiscall -arch=i386 ??0CHString@@QAE@ABV0@@Z(ptr) _ZN8CHStringC1ERKS_ +@ thiscall -arch=i386 ??0CHString@@QAE@PBD@Z(str) _ZN8CHStringC1EPKc +@ thiscall -arch=i386 ??0CHString@@QAE@PBE@Z(str) _ZN8CHStringC1EPKh +@ thiscall -arch=i386 ??0CHString@@QAE@PBG@Z(wstr) _ZN8CHStringC1EPKw +@ thiscall -arch=i386 ??0CHString@@QAE@PBGH@Z(wstr long) _ZN8CHStringC1EPKwi +@ thiscall -arch=i386 ??0CHString@@QAE@GH@Z(long long) _ZN8CHStringC1Ewi +@ thiscall -arch=i386 ??0CHString@@QAE@XZ() _ZN8CHStringC1Ev # public: __thiscall CHString::CHString(void) +@ thiscall -arch=i386 ?Collate@CHString@@QBEHPBG@Z(wstr) _ZNK8CHString7CollateEPKw # public: int __thiscall CHString::Collate(unsigned short const *)const +@ thiscall -arch=i386 ?Compare@CHString@@QBEHPBG@Z(wstr) _ZNK8CHString7CompareEPKw # public: int __thiscall CHString::Compare(unsigned short const *)const +@ thiscall -arch=i386 ?CompareNoCase@CHString@@QBEHPBG@Z(wstr) _ZNK8CHString13CompareNoCaseEPKw # public: int __thiscall CHString::CompareNoCase(unsigned short const *)const +@ thiscall -arch=i386 ?ConcatCopy@CHString@@IAEXHPBGH0@Z(long wstr long wstr) _ZN8CHString10ConcatCopyEiPKwiS1_ # protected: void __thiscall CHString::ConcatCopy(int,unsigned short const *,int,unsigned short const *) +@ thiscall -arch=i386 ?ConcatInPlace@CHString@@IAEXHPBG@Z(long wstr) _ZN8CHString13ConcatInPlaceEiPKw # protected: void __thiscall CHString::ConcatInPlace(int,unsigned short const *) +@ thiscall -arch=i386 ?CopyBeforeWrite@CHString@@IAEXXZ() _ZN8CHString15CopyBeforeWriteEv # protected: void __thiscall CHString::CopyBeforeWrite(void) +@ thiscall -arch=i386 ?Empty@CHString@@QAEXXZ() _ZN8CHString5EmptyEv # public: void __thiscall CHString::Empty(void) +@ thiscall -arch=i386 ?Find@CHString@@QBEHPBG@Z(wstr) _ZNK8CHString4FindEPKw # public: int __thiscall CHString::Find(unsigned short const *)const +@ thiscall -arch=i386 ?Find@CHString@@QBEHG@Z(long) _ZNK8CHString4FindEw # public: int __thiscall CHString::Find(unsigned short)const +@ thiscall -arch=i386 ?FindOneOf@CHString@@QBEHPBG@Z(wstr) _ZNK8CHString9FindOneOfEPKw # public: int __thiscall CHString::FindOneOf(unsigned short const *)const +@ thiscall -arch=i386 ?Format@CHString@@QAAXIZZ(long long long) _ZN8CHString6FormatEjz # public: void __cdecl CHString::Format(unsigned int,...) +@ thiscall -arch=i386 ?Format@CHString@@QAAXPBGZZ(long wstr long) _ZN8CHString6FormatEPKwz # public: void __cdecl CHString::Format(unsigned short const *,...) +@ thiscall -arch=i386 ?FormatMessageW@CHString@@QAAXIZZ(long long long) _ZN8CHString14FormatMessageWEjz # public: void __cdecl CHString::FormatMessageW(unsigned int,...) +@ thiscall -arch=i386 ?FormatMessageW@CHString@@QAAXPBGZZ(long ptr long) _ZN8CHString14FormatMessageWEPKwz # public: void __cdecl CHString::FormatMessageW(unsigned short const *,...) +@ thiscall -arch=i386 ?FormatV@CHString@@QAEXPBGPAD@Z(wstr long) _ZN8CHString7FormatVEPKwPc # public: void __thiscall CHString::FormatV(unsigned short const *,char *) +@ thiscall -arch=i386 ?FreeExtra@CHString@@QAEXXZ() _ZN8CHString9FreeExtraEv # public: void __thiscall CHString::FreeExtra(void) +@ thiscall -arch=i386 ?GetAllocLength@CHString@@QBEHXZ() _ZNK8CHString14GetAllocLengthEv # public: int __thiscall CHString::GetAllocLength(void)const +@ thiscall -arch=i386 ?GetAt@CHString@@QBEGH@Z(long) _ZNK8CHString5GetAtEi # public: unsigned short __thiscall CHString::GetAt(int)const +@ thiscall -arch=i386 ?GetBuffer@CHString@@QAEPAGH@Z(long) _ZN8CHString9GetBufferEi # public: unsigned short * __thiscall CHString::GetBuffer(int) +@ thiscall -arch=i386 ?GetBufferSetLength@CHString@@QAEPAGH@Z(long) _ZN8CHString18GetBufferSetLengthEi # public: unsigned short * __thiscall CHString::GetBufferSetLength(int) +@ thiscall -arch=i386 ?GetData@CHString@@IBEPAUCHStringData@@XZ() _ZNK8CHString7GetDataEv # protected: struct CHStringData * __thiscall CHString::GetData(void)const +@ thiscall -arch=i386 ?GetLength@CHString@@QBEHXZ() _ZNK8CHString9GetLengthEv # public: int __thiscall CHString::GetLength(void)const +@ thiscall -arch=i386 ?Init@CHString@@IAEXXZ() _ZN8CHString4InitEv # protected: void __thiscall CHString::Init(void) +@ thiscall -arch=i386 ?IsEmpty@CHString@@QBEHXZ() _ZNK8CHString7IsEmptyEv # public: int __thiscall CHString::IsEmpty(void)const +@ thiscall -arch=i386 ?Left@CHString@@QBE?AV1@H@Z(long) _ZNK8CHString4LeftEi # public: class CHString __thiscall CHString::Left(int)const +@ thiscall -arch=i386 ?LoadStringW@CHString@@QAEHI@Z(long) _ZN8CHString11LoadStringWEj # public: int __thiscall CHString::LoadStringW(unsigned int) +@ thiscall -arch=i386 ?LoadStringW@CHString@@IAEHIPAGI@Z(long wstr long) _ZN8CHString11LoadStringWEjPwj # protected: int __thiscall CHString::LoadStringW(unsigned int,unsigned short *,unsigned int) +@ thiscall -arch=i386 ?LockBuffer@CHString@@QAEPAGXZ() _ZN8CHString10LockBufferEv # public: unsigned short * __thiscall CHString::LockBuffer(void) +@ thiscall -arch=i386 ?MakeLower@CHString@@QAEXXZ() _ZN8CHString9MakeLowerEv # public: void __thiscall CHString::MakeLower(void) +@ thiscall -arch=i386 ?MakeReverse@CHString@@QAEXXZ() _ZN8CHString11MakeReverseEv # public: void __thiscall CHString::MakeReverse(void) +@ thiscall -arch=i386 ?MakeUpper@CHString@@QAEXXZ() _ZN8CHString9MakeUpperEv # public: void __thiscall CHString::MakeUpper(void) +@ thiscall -arch=i386 ?Mid@CHString@@QBE?AV1@H@Z(long) _ZNK8CHString3MidEi # public: class CHString __thiscall CHString::Mid(int)const +@ thiscall -arch=i386 ?Mid@CHString@@QBE?AV1@HH@Z(long long) _ZNK8CHString3MidEii # public: class CHString __thiscall CHString::Mid(int,int)const +@ thiscall -arch=i386 ?Release@CHString@@KGXPAUCHStringData@@@Z(ptr) _ZN8CHString7ReleaseEP12CHStringData@4 # protected: static void __stdcall CHString::Release(struct CHStringData *) +@ thiscall -arch=i386 ?Release@CHString@@IAEXXZ() _ZN8CHString7ReleaseEv # protected: void __thiscall CHString::Release(void) +@ thiscall -arch=i386 ?ReleaseBuffer@CHString@@QAEXH@Z(long) _ZN8CHString13ReleaseBufferEi # public: void __thiscall CHString::ReleaseBuffer(int) +@ thiscall -arch=i386 ?ReverseFind@CHString@@QBEHG@Z(long) _ZNK8CHString11ReverseFindEw # public: int __thiscall CHString::ReverseFind(unsigned short)const +@ thiscall -arch=i386 ?Right@CHString@@QBE?AV1@H@Z(long) _ZNK8CHString5RightEi # public: class CHString __thiscall CHString::Right(int)const +@ stdcall -arch=i386 ?SafeStrlen@CHString@@KGHPBG@Z(wstr) _ZN8CHString10SafeStrlenEPKw # protected: static int__stdcall CHString::SafeStrlen(unsigned short const *) +@ thiscall -arch=i386 ?SetAt@CHString@@QAEXHG@Z(long long) _ZN8CHString5SetAtEiw # public: void __thiscall CHString::SetAt(int,unsigned short) +@ thiscall -arch=i386 ?SpanExcluding@CHString@@QBE?AV1@PBG@Z(long wstr) _ZNK8CHString13SpanExcludingEPKw # public: class CHString __thiscall CHString::SpanExcluding(unsigned short const *)const +@ thiscall -arch=i386 ?SpanIncluding@CHString@@QBE?AV1@PBG@Z(long wstr) _ZNK8CHString13SpanIncludingEPKw # public: class CHString __thiscall CHString::SpanIncluding(unsigned short const *)const +@ thiscall -arch=i386 ?TrimLeft@CHString@@QAEXXZ() _ZN8CHString8TrimLeftEv # public: void __thiscall CHString::TrimLeft(void) +@ thiscall -arch=i386 ?TrimRight@CHString@@QAEXXZ() _ZN8CHString9TrimRightEv # public: void __thiscall CHString::TrimRight(void) +@ thiscall -arch=i386 ?UnlockBuffer@CHString@@QAEXXZ() _ZN8CHString12UnlockBufferEv # public: void __thiscall CHString::UnlockBuffer(void) +@ thiscall -arch=i386 ??BCHString@@QBEPBGXZ(ptr) _ZNK8CHStringcvPKwEv # public: __thiscall CHString::operator unsigned short const *(void)const +@ thiscall -arch=i386 ??YCHString@@QAEABV0@ABV0@@Z(ptr) _ZN8CHStringpLERKS_ # public: class CHString const & __thiscall CHString::operator+=(class CHString const &) +@ thiscall -arch=i386 ??YCHString@@QAEABV0@D@Z(long) _ZN8CHStringpLEc # public: class CHString const & __thiscall CHString::operator+=(char) +@ thiscall -arch=i386 ??YCHString@@QAEABV0@PBG@Z(wstr) _ZN8CHStringpLEPKw # public: class CHString const & __thiscall CHString::operator+=(unsigned short const *) +@ thiscall -arch=i386 ??YCHString@@QAEABV0@G@Z(long) _ZN8CHStringpLEw # public: class CHString const & __thiscall CHString::operator+=(unsigned short) +@ thiscall -arch=i386 ??4CHString@@QAEABV0@PAV0@@Z(ptr) _ZN8CHStringaSEPS_ # public: class CHString const & __thiscall CHString::operator=(class CHString *) +@ thiscall -arch=i386 ??4CHString@@QAEABV0@ABV0@@Z(ptr) _ZN8CHStringaSERKS_ # public: class CHString const & __thiscall CHString::operator=(class CHString const &) +@ thiscall -arch=i386 ??4CHString@@QAEABV0@PBD@Z(str) _ZN8CHStringaSEPKc # public: class CHString const & __thiscall CHString::operator=(char const *) +@ thiscall -arch=i386 ??4CHString@@QAEABV0@D@Z(long) _ZN8CHStringaSEc # public: class CHString const & __thiscall CHString::operator=(char) +@ thiscall -arch=i386 ??4CHString@@QAEABV0@PBE@Z(str) _ZN8CHStringaSEPKh # public: class CHString const & __thiscall CHString::operator=(unsigned char const *) +@ thiscall -arch=i386 ??4CHString@@QAEABV0@PBG@Z(wstr) _ZN8CHStringaSEPKw # public: class CHString const & __thiscall CHString::operator=(unsigned short const *) +@ thiscall -arch=i386 ??4CHString@@QAEABV0@G@Z(long) _ZN8CHStringaSEw # public: class CHString const & __thiscall CHString::operator=(unsigned short) +@ thiscall -arch=i386 ??ACHString@@QBEGH@Z(long) _ZNK8CHStringixEi # public: unsigned short __thiscall CHString::operator[](int)const +@ thiscall -arch=i386 ??1CHString@@QAE@XZ() _ZN8CHStringD1Ev # public: __thiscall CHString::~CHString(void), complete object destructor, identical to _ZN8CHStringD2Ev aka base object destructor +@ stdcall -arch=i386 ??H@YG?AVCHString@@GABV0@@Z(long ptr) _ZplwRK8CHString # class CHString __stdcall operator+(unsigned short,class CHString const &) +@ stdcall -arch=i386 ??H@YG?AVCHString@@ABV0@G@Z(ptr long) _ZplRK8CHStringw # class CHString __stdcall operator+(class CHString const &,unsigned short) +@ stdcall -arch=i386 ??H@YG?AVCHString@@ABV0@PBG@Z(ptr wstr) _ZplRK8CHStringPKw # class CHString __stdcall operator+(class CHString const &,unsigned short const *) +@ stdcall -arch=i386 ??H@YG?AVCHString@@PBGABV0@@Z(wstr ptr) _ZplPKwRK8CHString # class CHString __stdcall operator+(unsigned short const *,class CHString const &) +@ stdcall -arch=i386 ??H@YG?AVCHString@@ABV0@0@Z(ptr ptr) _ZplRK8CHStringS1_ # class CHString __stdcall operator+(class CHString const &,class CHString const &) +@ thiscall -arch=i386 ?Flush@Provider@@MAEXXZ() _ZN8Provider5FlushEv # protected: virtual void __thiscall Provider::Flush(void) +@ thiscall -arch=i386 ?ValidateDeletionFlags@Provider@@MAEJJ@Z(long) _ZN8Provider21ValidateDeletionFlagsEl # protected: virtual long __thiscall Provider::ValidateDeletionFlags(long) +@ thiscall -arch=i386 ?ValidateMethodFlags@Provider@@MAEJJ@Z(long) _ZN8Provider19ValidateMethodFlagsEl # protected: virtual long __thiscall Provider::ValidateMethodFlags(long) +@ thiscall -arch=i386 ?ValidateQueryFlags@Provider@@MAEJJ@Z(long) _ZN8Provider18ValidateQueryFlagsEl # protected: virtual long __thiscall Provider::ValidateQueryFlags(long) + +# **************** win64 exports **************** +@ thiscall -arch=win64 ?AllocBeforeWrite@CHString@@IEAAXH@Z(long) _ZN8CHString16AllocBeforeWriteEi # protected: void __thiscall CHString::AllocBeforeWrite(int) +@ thiscall -arch=win64 ?AllocBuffer@CHString@@IEAAXH@Z(long) _ZN8CHString11AllocBufferEi # protected: void __thiscall CHString::AllocBuffer(int) +@ thiscall -arch=win64 ?AllocCopy@CHString@@IEBAXAEAV1@HHH@Z(ptr long long long) _ZNK8CHString9AllocCopyERS_iii # protected: void __thiscall CHString::AllocCopy(class CHString &,int,int,int)const +@ thiscall -arch=win64 ?AllocSysString@CHString@@QEBAPEAGXZ() _ZNK8CHString14AllocSysStringEv +@ thiscall -arch=win64 ?AssignCopy@CHString@@IEAAXHPEBG@Z(long wstr) _ZN8CHString10AssignCopyEiPKw +@ thiscall -arch=win64 ??0CHString@@QEAA@AEBV0@@Z(ptr) _ZN8CHStringC1ERKS_ +@ thiscall -arch=win64 ??0CHString@@QEAA@PEBD@Z(str) _ZN8CHStringC1EPKc +@ thiscall -arch=win64 ??0CHString@@QEAA@PEBE@Z(str) _ZN8CHStringC1EPKh +@ thiscall -arch=win64 ??0CHString@@QEAA@PEBG@Z(wstr) _ZN8CHStringC1EPKw +@ thiscall -arch=win64 ??0CHString@@QEAA@PEBGH@Z(wstr long) _ZN8CHStringC1EPKwi +@ thiscall -arch=win64 ??0CHString@@QEAA@GH@Z(long long) _ZN8CHStringC1Ewi +@ thiscall -arch=win64 ??0CHString@@QEAA@XZ() _ZN8CHStringC1Ev # public: __thiscall CHString::CHString(void) +@ thiscall -arch=win64 ?Collate@CHString@@QEBAHPEBG@Z(wstr) _ZNK8CHString7CollateEPKw # public: int __thiscall CHString::Collate(unsigned short const *)const +@ thiscall -arch=win64 ?Compare@CHString@@QEBAHPEBG@Z(wstr) _ZNK8CHString7CompareEPKw # public: int __thiscall CHString::Compare(unsigned short const *)const +@ thiscall -arch=win64 ?CompareNoCase@CHString@@QEBAHPEBG@Z(wstr) _ZNK8CHString13CompareNoCaseEPKw # public: int __thiscall CHString::CompareNoCase(unsigned short const *)const +@ thiscall -arch=win64 ?ConcatCopy@CHString@@IEAAXHPEBGH0@Z(long wstr long wstr) _ZN8CHString10ConcatCopyEiPKwiS1_ # protected: void __thiscall CHString::ConcatCopy(int,unsigned short const *,int,unsigned short const *) +@ thiscall -arch=win64 ?ConcatInPlace@CHString@@IEAAXHPEBG@Z(long wstr) _ZN8CHString13ConcatInPlaceEiPKw # protected: void __thiscall CHString::ConcatInPlace(int,unsigned short const *) +@ thiscall -arch=win64 ?CopyBeforeWrite@CHString@@IEAAXXZ() _ZN8CHString15CopyBeforeWriteEv # protected: void __thiscall CHString::CopyBeforeWrite(void) +@ thiscall -arch=win64 ?Empty@CHString@@QEAAXXZ() _ZN8CHString5EmptyEv # public: void __thiscall CHString::Empty(void) +@ thiscall -arch=win64 ?Find@CHString@@QEBAHPEBG@Z(wstr) _ZNK8CHString4FindEPKw # public: int __thiscall CHString::Find(unsigned short const *)const +@ thiscall -arch=win64 ?Find@CHString@@QEBAHG@Z(long) _ZNK8CHString4FindEPKw # public: int __thiscall CHString::Find(unsigned short)const +@ thiscall -arch=win64 ?FindOneOf@CHString@@QEBAHPEBG@Z(wstr) _ZNK8CHString9FindOneOfEPKw # public: int __thiscall CHString::FindOneOf(unsigned short const *)const +@ thiscall -arch=win64 ?Format@CHString@@QEAAXIZZ(long long long) _ZN8CHString6FormatEjz # public: void __cdecl CHString::Format(unsigned int,...) +@ thiscall -arch=win64 ?Format@CHString@@QEAAXPEBGZZ(long wstr long) _ZN8CHString6FormatEPKwz # public: void __cdecl CHString::Format(unsigned short const *,...) +@ thiscall -arch=win64 ?FormatMessageW@CHString@@QEAAXIZZ(long long long) _ZN8CHString14FormatMessageWEjz # public: void __cdecl CHString::FormatMessageW(unsigned int,...) +@ thiscall -arch=win64 ?FormatMessageW@CHString@@QEAAXPEBGZZ(long ptr long) _ZN8CHString14FormatMessageWEPKwz # public: void __cdecl CHString::FormatMessageW(unsigned short const *,...) +@ thiscall -arch=win64 ?FormatV@CHString@@QEAAXPEBGPEAD@Z(wstr long) _ZN8CHString7FormatVEPKwPc # public: void __thiscall CHString::FormatV(unsigned short const *,char *) +@ thiscall -arch=win64 ?FreeExtra@CHString@@QEAAXXZ() _ZN8CHString9FreeExtraEv # public: void __thiscall CHString::FreeExtra(void) +@ thiscall -arch=win64 ?GetAllocLength@CHString@@QEBAHXZ() _ZNK8CHString14GetAllocLengthEv # public: int __thiscall CHString::GetAllocLength(void)const +@ thiscall -arch=win64 ?GetAt@CHString@@QEBAGH@Z(long) _ZNK8CHString5GetAtEi # public: unsigned short __thiscall CHString::GetAt(int)const +@ thiscall -arch=win64 ?GetBuffer@CHString@@QEAAPEAGH@Z(long) _ZN8CHString9GetBufferEi # public: unsigned short * __thiscall CHString::GetBuffer(int) +@ thiscall -arch=win64 ?GetBufferSetLength@CHString@@QEAAPEAGH@Z(long) _ZN8CHString18GetBufferSetLengthEi # public: unsigned short * __thiscall CHString::GetBufferSetLength(int) +@ thiscall -arch=win64 ?GetData@CHString@@IEBAPEAUCHStringData@@XZ() _ZNK8CHString7GetDataEv # protected: struct CHStringData * __thiscall CHString::GetData(void)const +@ thiscall -arch=win64 ?GetLength@CHString@@QEBAHXZ() _ZNK8CHString9GetLengthEv # public: int __thiscall CHString::GetLength(void)const +@ thiscall -arch=win64 ?Init@CHString@@IEAAXXZ() _ZN8CHString4InitEv # protected: void __thiscall CHString::Init(void) +@ thiscall -arch=win64 ?IsEmpty@CHString@@QEBAHXZ() _ZNK8CHString7IsEmptyEv # public: int __thiscall CHString::IsEmpty(void)const +@ thiscall -arch=win64 ?Left@CHString@@QEBA?AV1@H@Z(long) _ZNK8CHString4LeftEi # public: class CHString __thiscall CHString::Left(int)const +@ thiscall -arch=win64 ?LoadStringW@CHString@@QEAAHI@Z(long) _ZN8CHString11LoadStringWEj # public: int __thiscall CHString::LoadStringW(unsigned int) +@ thiscall -arch=win64 ?LoadStringW@CHString@@IEAAHIPEAGI@Z(long wstr long) _ZN8CHString11LoadStringWEjPwj # protected: int __thiscall CHString::LoadStringW(unsigned int,unsigned short *,unsigned int) +@ thiscall -arch=win64 ?LockBuffer@CHString@@QEAAPEAGXZ() _ZN8CHString10LockBufferEv # public: unsigned short * __thiscall CHString::LockBuffer(void) +@ thiscall -arch=win64 ?MakeLower@CHString@@QEAAXXZ() _ZN8CHString9MakeLowerEv # public: void __thiscall CHString::MakeLower(void) +@ thiscall -arch=win64 ?MakeReverse@CHString@@QEAAXXZ() _ZN8CHString11MakeReverseEv # public: void __thiscall CHString::MakeReverse(void) +@ thiscall -arch=win64 ?MakeUpper@CHString@@QEAAXXZ() _ZN8CHString9MakeUpperEv # public: void __thiscall CHString::MakeUpper(void) +@ thiscall -arch=win64 ?Mid@CHString@@QEBA?AV1@H@Z(long) _ZNK8CHString3MidEi # public: class CHString __thiscall CHString::Mid(int)const +@ thiscall -arch=win64 ?Mid@CHString@@QEBA?AV1@HH@Z(long long) _ZNK8CHString3MidEii # public: class CHString __thiscall CHString::Mid(int,int)const +@ thiscall -arch=win64 ?Release@CHString@@KAXPEAUCHStringData@@@Z(ptr) _ZN8CHString7ReleaseEP12CHStringData@4 # protected: static void __stdcall CHString::Release(struct CHStringData *) +@ thiscall -arch=win64 ?Release@CHString@@IEAAXXZ() _ZN8CHString7ReleaseEv # protected: void __thiscall CHString::Release(void) +@ thiscall -arch=win64 ?ReleaseBuffer@CHString@@QEAAXH@Z(long) _ZN8CHString13ReleaseBufferEi # public: void __thiscall CHString::ReleaseBuffer(int) +@ thiscall -arch=win64 ?ReverseFind@CHString@@QEBAHG@Z(long) _ZNK8CHString11ReverseFindEw # public: int __thiscall CHString::ReverseFind(unsigned short)const +@ thiscall -arch=win64 ?Right@CHString@@QEBA?AV1@H@Z(long) _ZNK8CHString5RightEi # public: class CHString __thiscall CHString::Right(int)const +@ stdcall -arch=win64 ?SafeStrlen@CHString@@KAHPEBG@Z(wstr) _ZN8CHString10SafeStrlenEPKw # protected: static int__stdcall CHString::SafeStrlen(unsigned short const *) +@ thiscall -arch=win64 ?SetAt@CHString@@QEAAXHG@Z(long long) _ZN8CHString5SetAtEiw # public: void __thiscall CHString::SetAt(int,unsigned short) +@ thiscall -arch=win64 ?SpanExcluding@CHString@@QEBA?AV1@PEBG@Z(long wstr) _ZNK8CHString13SpanExcludingEPKw # public: class CHString __thiscall CHString::SpanExcluding(unsigned short const *)const +@ thiscall -arch=win64 ?SpanIncluding@CHString@@QEBA?AV1@PEBG@Z(long wstr) _ZNK8CHString13SpanIncludingEPKw # public: class CHString __thiscall CHString::SpanIncluding(unsigned short const *)const +@ thiscall -arch=win64 ?TrimLeft@CHString@@QEAAXXZ() _ZN8CHString8TrimLeftEv # public: void __thiscall CHString::TrimLeft(void) +@ thiscall -arch=win64 ?TrimRight@CHString@@QEAAXXZ() _ZN8CHString9TrimRightEv # public: void __thiscall CHString::TrimRight(void) +@ thiscall -arch=win64 ?UnlockBuffer@CHString@@QEAAXXZ() _ZN8CHString12UnlockBufferEv # public: void __thiscall CHString::UnlockBuffer(void) +@ thiscall -arch=win64 ??BCHString@@QEBAPEBGXZ(ptr) _ZNK8CHStringcvPKwEv # public: __thiscall CHString::operator unsigned short const *(void)const +@ thiscall -arch=win64 ??YCHString@@QEAAAEBV0@AEBV0@@Z(ptr) _ZN8CHStringpLERKS_ # public: class CHString const & __thiscall CHString::operator+=(class CHString const &) +@ thiscall -arch=win64 ??YCHString@@QEAAAEBV0@D@Z(long) _ZN8CHStringpLEc # public: class CHString const & __thiscall CHString::operator+=(char) +@ thiscall -arch=win64 ??YCHString@@QEAAAEBV0@PEBG@Z(wstr) _ZN8CHStringpLEPKw # public: class CHString const & __thiscall CHString::operator+=(unsigned short const *) +@ thiscall -arch=win64 ??YCHString@@QEAAAEBV0@G@Z(long) _ZN8CHStringpLEw # public: class CHString const & __thiscall CHString::operator+=(unsigned short) +@ thiscall -arch=win64 ??4CHString@@QEAAAEBV0@PEAV0@@Z(ptr) _ZN8CHStringaSEPS_ # public: class CHString const & __thiscall CHString::operator=(class CHString *) +@ thiscall -arch=win64 ??4CHString@@QEAAAEBV0@AEBV0@@Z(ptr) _ZN8CHStringaSERKS_ # public: class CHString const & __thiscall CHString::operator=(class CHString const &) +@ thiscall -arch=win64 ??4CHString@@QEAAAEBV0@PEBD@Z(str) _ZN8CHStringaSEPKc # public: class CHString const & __thiscall CHString::operator=(char const *) +@ thiscall -arch=win64 ??4CHString@@QEAAAEBV0@D@Z(long) _ZN8CHStringaSEc # public: class CHString const & __thiscall CHString::operator=(char) +@ thiscall -arch=win64 ??4CHString@@QEAAAEBV0@PEBE@Z(str) _ZN8CHStringaSEPKh # public: class CHString const & __thiscall CHString::operator=(unsigned char const *) +@ thiscall -arch=win64 ??4CHString@@QEAAAEBV0@PEBG@Z(wstr) _ZN8CHStringaSEPKw # public: class CHString const & __thiscall CHString::operator=(unsigned short const *) +@ thiscall -arch=win64 ??4CHString@@QEAAAEBV0@G@Z(long) _ZN8CHStringaSEw # public: class CHString const & __thiscall CHString::operator=(unsigned short) +@ thiscall -arch=win64 ??ACHString@@QEBAGH@Z(long) _ZNK8CHStringixEi # public: unsigned short __thiscall CHString::operator[](int)const +@ thiscall -arch=win64 ??1CHString@@QEAA@XZ() _ZN8CHStringD1Ev # public: __thiscall CHString::~CHString(void), complete object destructor, identical to _ZN8CHStringD2Ev aka base object destructor +@ stdcall -arch=win64 ??H@YA?AVCHString@@GAEBV0@@Z(long ptr) _ZplwRK8CHString # class CHString __stdcall operator+(unsigned short,class CHString const &) +@ stdcall -arch=win64 ??H@YA?AVCHString@@AEBV0@G@Z(ptr long) _ZplRK8CHStringw # class CHString __stdcall operator+(class CHString const &,unsigned short) +@ stdcall -arch=win64 ??H@YA?AVCHString@@AEBV0@PEBG@Z(ptr wstr) _ZplRK8CHStringPKw # class CHString __stdcall operator+(class CHString const &,unsigned short const *) +@ stdcall -arch=win64 ??H@YA?AVCHString@@PEBGAEBV0@@Z(wstr ptr) _ZplPKwRK8CHString # class CHString __stdcall operator+(unsigned short const *,class CHString const &) +@ stdcall -arch=win64 ??H@YA?AVCHString@@AEBV0@0@Z(ptr ptr) _ZplRK8CHStringS1_ # class CHString __stdcall operator+(class CHString const &,class CHString const &) +@ thiscall -arch=win64 ?Flush@Provider@@MEAAXXZ() _ZN8Provider5FlushEv # protected: virtual void __thiscall Provider::Flush(void) +@ thiscall -arch=win64 ?ValidateDeletionFlags@Provider@@MEAAJJ@Z(long) _ZN8Provider21ValidateDeletionFlagsEl # protected: virtual long __thiscall Provider::ValidateDeletionFlags(long) +@ thiscall -arch=win64 ?ValidateMethodFlags@Provider@@MEAAJJ@Z(long) _ZN8Provider19ValidateMethodFlagsEl # protected: virtual long __thiscall Provider::ValidateMethodFlags(long) +@ thiscall -arch=win64 ?ValidateQueryFlags@Provider@@MEAAJJ@Z(long) _ZN8Provider18ValidateQueryFlagsEl # protected: virtual long __thiscall Provider::ValidateQueryFlags(long) + +# **************** arm exports **************** +;@ cdecl -arch=arm ??0CAutoEvent@@QAA@XZ() +;@ cdecl -arch=arm ??0CFrameworkQuery@@QAA@ABV0@@Z() +;@ cdecl -arch=arm ??0CFrameworkQuery@@QAA@XZ() +;@ cdecl -arch=arm ??0CFrameworkQueryEx@@QAA@ABV0@@Z() +;@ cdecl -arch=arm ??0CFrameworkQueryEx@@QAA@XZ() +;@ cdecl -arch=arm ??0CHPtrArray@@QAA@XZ() +@ cdecl -arch=arm ??0CHString@@QAA@ABV0@@Z() +@ cdecl -arch=arm ??0CHString@@QAA@GH@Z() +@ cdecl -arch=arm ??0CHString@@QAA@PBD@Z() +@ cdecl -arch=arm ??0CHString@@QAA@PBE@Z() +@ cdecl -arch=arm ??0CHString@@QAA@PBG@Z() +@ cdecl -arch=arm ??0CHString@@QAA@PBGH@Z() +@ cdecl -arch=arm ??0CHString@@QAA@XZ() +;@ cdecl -arch=arm ??0CHStringArray@@QAA@XZ() +;@ cdecl -arch=arm ??0CInstance@@QAA@ABV0@@Z() +;@ cdecl -arch=arm ??0CInstance@@QAA@PAUIWbemClassObject@@PAVMethodContext@@@Z() +;@ cdecl -arch=arm ??0CObjectPathParser@@QAA@W4ObjectParserFlags@@@Z() +;@ cdecl -arch=arm ??0CRegistry@@QAA@ABV0@@Z() +;@ cdecl -arch=arm ??0CRegistry@@QAA@XZ() +;@ cdecl -arch=arm ??0CRegistrySearch@@QAA@ABV0@@Z() +;@ cdecl -arch=arm ??0CRegistrySearch@@QAA@XZ() +;@ cdecl -arch=arm ??0CThreadBase@@QAA@ABV0@@Z() +;@ cdecl -arch=arm ??0CThreadBase@@QAA@W4THREAD_SAFETY_MECHANISM@0@@Z() +;@ cdecl -arch=arm ??0CWbemGlueFactory@@QAA@ABV0@@Z() +;@ cdecl -arch=arm ??0CWbemGlueFactory@@QAA@PAJ@Z() +;@ cdecl -arch=arm ??0CWbemGlueFactory@@QAA@XZ() +;@ cdecl -arch=arm ??0CWbemProviderGlue@@QAA@ABV0@@Z() +;@ cdecl -arch=arm ??0CWbemProviderGlue@@QAA@PAJ@Z() +;@ cdecl -arch=arm ??0CWbemProviderGlue@@QAA@XZ() +;@ cdecl -arch=arm ??0CWinMsgEvent@@QAA@ABV0@@Z() +;@ cdecl -arch=arm ??0CWinMsgEvent@@QAA@XZ() +;@ cdecl -arch=arm ??0CreateMutexAsProcess@@QAA@PBG@Z() +;@ cdecl -arch=arm ??0KeyRef@@QAA@PBGPBUtagVARIANT@@@Z() +;@ cdecl -arch=arm ??0KeyRef@@QAA@XZ() +;@ cdecl -arch=arm ??0MethodContext@@QAA@ABV0@@Z() +;@ cdecl -arch=arm ??0MethodContext@@QAA@PAUIWbemContext@@PAVCWbemProviderGlue@@@Z() +;@ cdecl -arch=arm ??0ParsedObjectPath@@QAA@XZ() +;@ cdecl -arch=arm ??0Provider@@QAA@ABV0@@Z() +;@ cdecl -arch=arm ??0Provider@@QAA@PBG0@Z() +;@ cdecl -arch=arm ??0ProviderLog@@QAA@ABV0@@Z() +;@ cdecl -arch=arm ??0ProviderLog@@QAA@XZ() +;@ cdecl -arch=arm ??0WBEMTime@@QAA@ABJ@Z() +;@ cdecl -arch=arm ??0WBEMTime@@QAA@ABU_FILETIME@@@Z() +;@ cdecl -arch=arm ??0WBEMTime@@QAA@ABU_SYSTEMTIME@@@Z() +;@ cdecl -arch=arm ??0WBEMTime@@QAA@ABUtm@@@Z() +;@ cdecl -arch=arm ??0WBEMTime@@QAA@QAG@Z() +;@ cdecl -arch=arm ??0WBEMTime@@QAA@XZ() +;@ cdecl -arch=arm ??0WBEMTimeSpan@@QAA@ABJ@Z() +;@ cdecl -arch=arm ??0WBEMTimeSpan@@QAA@ABU_FILETIME@@@Z() +;@ cdecl -arch=arm ??0WBEMTimeSpan@@QAA@HHHHHHH@Z() +;@ cdecl -arch=arm ??0WBEMTimeSpan@@QAA@QAG@Z() +;@ cdecl -arch=arm ??0WBEMTimeSpan@@QAA@XZ() +;@ cdecl -arch=arm ??0_Lockit@std@@QAA@XZ() +;@ cdecl -arch=arm ??1CAutoEvent@@QAA@XZ() +;@ cdecl -arch=arm ??1CFrameworkQuery@@QAA@XZ() +;@ cdecl -arch=arm ??1CFrameworkQueryEx@@QAA@XZ() +;@ cdecl -arch=arm ??1CHPtrArray@@QAA@XZ() +@ cdecl -arch=arm ??1CHString@@QAA@XZ() +;@ cdecl -arch=arm ??1CHStringArray@@QAA@XZ() +;@ cdecl -arch=arm ??1CInstance@@UAA@XZ() +;@ cdecl -arch=arm ??1CObjectPathParser@@QAA@XZ() +;@ cdecl -arch=arm ??1CRegistry@@QAA@XZ() +;@ cdecl -arch=arm ??1CRegistrySearch@@QAA@XZ() +;@ cdecl -arch=arm ??1CThreadBase@@UAA@XZ() +;@ cdecl -arch=arm ??1CWbemGlueFactory@@QAA@XZ() +;@ cdecl -arch=arm ??1CWbemProviderGlue@@QAA@XZ() +;@ cdecl -arch=arm ??1CWinMsgEvent@@QAA@XZ() +;@ cdecl -arch=arm ??1CreateMutexAsProcess@@QAA@XZ() +;@ cdecl -arch=arm ??1KeyRef@@QAA@XZ() +;@ cdecl -arch=arm ??1MethodContext@@UAA@XZ() +;@ cdecl -arch=arm ??1ParsedObjectPath@@QAA@XZ() +;@ cdecl -arch=arm ??1Provider@@UAA@XZ() +;@ cdecl -arch=arm ??1ProviderLog@@UAA@XZ() +;@ cdecl -arch=arm ??1_Lockit@std@@QAA@XZ() +;@ cdecl -arch=arm ??4CAutoEvent@@QAAAAV0@ABV0@@Z() +;@ cdecl -arch=arm ??4CFrameworkQuery@@QAAAAV0@ABV0@@Z() +;@ cdecl -arch=arm ??4CFrameworkQueryEx@@QAAAAV0@ABV0@@Z() +;@ cdecl -arch=arm ??4CHPtrArray@@QAAAAV0@ABV0@@Z() +@ cdecl -arch=arm ??4CHString@@QAAABV0@ABV0@@Z() +@ cdecl -arch=arm ??4CHString@@QAAABV0@D@Z() +@ cdecl -arch=arm ??4CHString@@QAAABV0@G@Z() +@ cdecl -arch=arm ??4CHString@@QAAABV0@PAV0@@Z() +@ cdecl -arch=arm ??4CHString@@QAAABV0@PBD@Z() +@ cdecl -arch=arm ??4CHString@@QAAABV0@PBE@Z() +@ cdecl -arch=arm ??4CHString@@QAAABV0@PBG@Z() +;@ cdecl -arch=arm ??4CHStringArray@@QAAAAV0@ABV0@@Z() +;@ cdecl -arch=arm ??4CInstance@@QAAAAV0@ABV0@@Z() +;@ cdecl -arch=arm ??4CObjectPathParser@@QAAAAV0@ABV0@@Z() +;@ cdecl -arch=arm ??4CRegistry@@QAAAAV0@ABV0@@Z() +;@ cdecl -arch=arm ??4CRegistrySearch@@QAAAAV0@ABV0@@Z() +;@ cdecl -arch=arm ??4CThreadBase@@QAAAAV0@ABV0@@Z() +;@ cdecl -arch=arm ??4CWbemGlueFactory@@QAAAAV0@ABV0@@Z() +;@ cdecl -arch=arm ??4CWbemProviderGlue@@QAAAAV0@ABV0@@Z() +;@ cdecl -arch=arm ??4CWinMsgEvent@@QAAAAV0@ABV0@@Z() +;@ cdecl -arch=arm ??4CreateMutexAsProcess@@QAAAAV0@ABV0@@Z() +;@ cdecl -arch=arm ??4KeyRef@@QAAAAU0@ABU0@@Z() +;@ cdecl -arch=arm ??4MethodContext@@QAAAAV0@ABV0@@Z() +;@ cdecl -arch=arm ??4ParsedObjectPath@@QAAAAU0@ABU0@@Z() +;@ cdecl -arch=arm ??4Provider@@QAAAAV0@ABV0@@Z() +;@ cdecl -arch=arm ??4ProviderLog@@QAAAAV0@ABV0@@Z() +;@ cdecl -arch=arm ??4WBEMTime@@QAAAAV0@ABV0@@Z() +;@ cdecl -arch=arm ??4WBEMTime@@QAAABV0@ABJ@Z() +;@ cdecl -arch=arm ??4WBEMTime@@QAAABV0@ABU_FILETIME@@@Z() +;@ cdecl -arch=arm ??4WBEMTime@@QAAABV0@ABU_SYSTEMTIME@@@Z() +;@ cdecl -arch=arm ??4WBEMTime@@QAAABV0@ABUtm@@@Z() +;@ cdecl -arch=arm ??4WBEMTime@@QAAABV0@QAG@Z() +;@ cdecl -arch=arm ??4WBEMTimeSpan@@QAAAAV0@ABV0@@Z() +;@ cdecl -arch=arm ??4WBEMTimeSpan@@QAAABV0@ABJ@Z() +;@ cdecl -arch=arm ??4WBEMTimeSpan@@QAAABV0@ABU_FILETIME@@@Z() +;@ cdecl -arch=arm ??4WBEMTimeSpan@@QAAABV0@QAG@Z() +;@ cdecl -arch=arm ??8WBEMTime@@QBAHABV0@@Z() +;@ cdecl -arch=arm ??8WBEMTimeSpan@@QBAHABV0@@Z() +;@ cdecl -arch=arm ??9WBEMTime@@QBAHABV0@@Z() +;@ cdecl -arch=arm ??9WBEMTimeSpan@@QBAHABV0@@Z() +;@ cdecl -arch=arm ??ACHPtrArray@@QAAAAPAXH@Z() +;@ cdecl -arch=arm ??ACHPtrArray@@QBAPAXH@Z() +@ cdecl -arch=arm ??ACHString@@QBAGH@Z() +;@ cdecl -arch=arm ??ACHStringArray@@QAAAAVCHString@@H@Z() +;@ cdecl -arch=arm ??ACHStringArray@@QBA?AVCHString@@H@Z() +@ cdecl -arch=arm ??BCHString@@QBAPBGXZ() +;@ cdecl -arch=arm ??GWBEMTime@@QAA?AVWBEMTimeSpan@@ABV0@@Z() +;@ cdecl -arch=arm ??GWBEMTime@@QBA?AV0@ABVWBEMTimeSpan@@@Z() +;@ cdecl -arch=arm ??GWBEMTimeSpan@@QBA?AV0@ABV0@@Z() +@ cdecl -arch=arm ??H@YA?AVCHString@@ABV0@0@Z() +@ cdecl -arch=arm ??H@YA?AVCHString@@ABV0@G@Z() +@ cdecl -arch=arm ??H@YA?AVCHString@@ABV0@PBG@Z() +@ cdecl -arch=arm ??H@YA?AVCHString@@GABV0@@Z() +@ cdecl -arch=arm ??H@YA?AVCHString@@PBGABV0@@Z() +;@ cdecl -arch=arm ??HWBEMTime@@QBA?AV0@ABVWBEMTimeSpan@@@Z() +;@ cdecl -arch=arm ??HWBEMTimeSpan@@QBA?AV0@ABV0@@Z() +;@ cdecl -arch=arm ??MWBEMTime@@QBAHABV0@@Z() +;@ cdecl -arch=arm ??MWBEMTimeSpan@@QBAHABV0@@Z() +;@ cdecl -arch=arm ??NWBEMTime@@QBAHABV0@@Z() +;@ cdecl -arch=arm ??NWBEMTimeSpan@@QBAHABV0@@Z() +;@ cdecl -arch=arm ??OWBEMTime@@QBAHABV0@@Z() +;@ cdecl -arch=arm ??OWBEMTimeSpan@@QBAHABV0@@Z() +;@ cdecl -arch=arm ??PWBEMTime@@QBAHABV0@@Z() +;@ cdecl -arch=arm ??PWBEMTimeSpan@@QBAHABV0@@Z() +@ cdecl -arch=arm ??YCHString@@QAAABV0@ABV0@@Z() +@ cdecl -arch=arm ??YCHString@@QAAABV0@D@Z() +@ cdecl -arch=arm ??YCHString@@QAAABV0@G@Z() +@ cdecl -arch=arm ??YCHString@@QAAABV0@PBG@Z() +;@ cdecl -arch=arm ??YWBEMTime@@QAAABV0@ABVWBEMTimeSpan@@@Z() +;@ cdecl -arch=arm ??YWBEMTimeSpan@@QAAABV0@ABV0@@Z() +;@ cdecl -arch=arm ??ZWBEMTime@@QAAABV0@ABVWBEMTimeSpan@@@Z() +;@ cdecl -arch=arm ??ZWBEMTimeSpan@@QAAABV0@ABV0@@Z() +;@ extern -arch=arm ??_7CFrameworkQueryEx@@6B@ +;@ extern -arch=arm ??_7CInstance@@6B@ +;@ extern -arch=arm ??_7CThreadBase@@6B@ +;@ extern -arch=arm ??_7CWbemGlueFactory@@6B@ +;@ extern -arch=arm ??_7CWbemProviderGlue@@6BIWbemProviderInit@@@ +;@ extern -arch=arm ??_7CWbemProviderGlue@@6BIWbemServices@@@ +;@ extern -arch=arm ??_7CWinMsgEvent@@6B@ +;@ extern -arch=arm ??_7MethodContext@@6B@ +;@ extern -arch=arm ??_7Provider@@6B@ +;@ cdecl -arch=arm ??_7ProviderLog@@6B@() +;@ cdecl -arch=arm ??_FCObjectPathParser@@QAAXXZ() +;@ cdecl -arch=arm ??_FCThreadBase@@QAAXXZ() +;@ cdecl -arch=arm ?Add@CHPtrArray@@QAAHPAX@Z() +;@ cdecl -arch=arm ?Add@CHStringArray@@QAAHPBG@Z() +;@ cdecl -arch=arm ?AddFlushPtr@CWbemProviderGlue@@AAAXPAX@Z() +;@ cdecl -arch=arm ?AddKeyRef@ParsedObjectPath@@QAAHPAUKeyRef@@@Z() +;@ cdecl -arch=arm ?AddKeyRef@ParsedObjectPath@@QAAHPBGPBUtagVARIANT@@@Z() +;@ cdecl -arch=arm ?AddKeyRefEx@ParsedObjectPath@@QAAHPBGPBUtagVARIANT@@@Z() +;@ cdecl -arch=arm ?AddNamespace@ParsedObjectPath@@QAAHPBG@Z() +;@ cdecl -arch=arm ?AddProviderToMap@CWbemProviderGlue@@CAPAVProvider@@PBG0PAV2@@Z() +;@ cdecl -arch=arm ?AddRef@CInstance@@QAAJXZ() +;@ cdecl -arch=arm ?AddRef@CThreadBase@@QAAJXZ() +;@ cdecl -arch=arm ?AddRef@CWbemGlueFactory@@UAAKXZ() +;@ cdecl -arch=arm ?AddRef@CWbemProviderGlue@@UAAKXZ() +;@ cdecl -arch=arm ?AddRef@MethodContext@@QAAJXZ() +;@ cdecl -arch=arm ?AddToFactoryMap@CWbemProviderGlue@@KAXPBVCWbemGlueFactory@@PAJ@Z() +;@ cdecl -arch=arm ?AllPropertiesAreRequired@CFrameworkQuery@@QAA_NXZ() +@ cdecl -arch=arm ?AllocBeforeWrite@CHString@@IAAXH@Z() +@ cdecl -arch=arm ?AllocBuffer@CHString@@IAAXH@Z() +@ cdecl -arch=arm ?AllocCopy@CHString@@IBAXAAV1@HHH@Z() +@ cdecl -arch=arm ?AllocSysString@CHString@@QBAPAGXZ() +;@ cdecl -arch=arm ?Append@CHPtrArray@@QAAHABV1@@Z() +;@ cdecl -arch=arm ?Append@CHStringArray@@QAAHABV1@@Z() +@ cdecl -arch=arm ?AssignCopy@CHString@@IAAXHPBG@Z() +;@ cdecl -arch=arm ?BeginRead@CThreadBase@@QAAHK@Z() +;@ cdecl -arch=arm ?BeginWrite@CThreadBase@@QAAHK@Z() +;@ cdecl -arch=arm ?CancelAsyncCall@CWbemProviderGlue@@UAAJPAUIWbemObjectSink@@@Z() +;@ cdecl -arch=arm ?CancelAsyncRequest@CWbemProviderGlue@@UAAJJ@Z() +;@ cdecl -arch=arm ?CheckAndAddToList@CRegistrySearch@@AAAXPAVCRegistry@@VCHString@@1AAVCHPtrArray@@11H@Z() +;@ cdecl -arch=arm ?CheckFileSize@ProviderLog@@AAAXAAT_LARGE_INTEGER@@ABVCHString@@@Z() +;@ cdecl -arch=arm ?CheckImpersonationLevel@CWbemProviderGlue@@CAJXZ() +;@ cdecl -arch=arm ?Clear@WBEMTime@@QAAXXZ() +;@ cdecl -arch=arm ?Clear@WBEMTimeSpan@@QAAXXZ() +;@ cdecl -arch=arm ?ClearKeys@ParsedObjectPath@@QAAXXZ() +;@ cdecl -arch=arm ?Close@CRegistry@@QAAXXZ() +;@ cdecl -arch=arm ?CloseSubKey@CRegistry@@AAAXXZ() +@ cdecl -arch=arm ?Collate@CHString@@QBAHPBG@Z() +;@ cdecl -arch=arm ?Commit@CInstance@@QAAJXZ() +;@ cdecl -arch=arm ?Commit@Provider@@IAAJPAVCInstance@@_N@Z() +@ cdecl -arch=arm ?Compare@CHString@@QBAHPBG@Z() +@ cdecl -arch=arm ?CompareNoCase@CHString@@QBAHPBG@Z() +@ cdecl -arch=arm ?ConcatCopy@CHString@@IAAXHPBGH0@Z() +@ cdecl -arch=arm ?ConcatInPlace@CHString@@IAAXHPBG@Z() +;@ cdecl -arch=arm ?Copy@CHPtrArray@@QAAXABV1@@Z() +;@ cdecl -arch=arm ?Copy@CHStringArray@@QAAXABV1@@Z() +@ cdecl -arch=arm ?CopyBeforeWrite@CHString@@IAAXXZ() +;@ cdecl -arch=arm ?Create@CWbemGlueFactory@@SAPAV1@PAJ@Z() +;@ cdecl -arch=arm ?Create@CWbemGlueFactory@@SAPAV1@XZ() +;@ cdecl -arch=arm ?CreateClassEnum@CWbemProviderGlue@@UAAJQAGJPAUIWbemContext@@PAPAUIEnumWbemClassObject@@@Z() +;@ cdecl -arch=arm ?CreateClassEnumAsync@CWbemProviderGlue@@UAAJQAGJPAUIWbemContext@@PAUIWbemObjectSink@@@Z() +;@ cdecl -arch=arm ?CreateInstance@CWbemGlueFactory@@UAAJPAUIUnknown@@ABU_GUID@@PAPAX@Z() +;@ cdecl -arch=arm ?CreateInstanceEnum@CWbemProviderGlue@@UAAJQAGJPAUIWbemContext@@PAPAUIEnumWbemClassObject@@@Z() +;@ cdecl -arch=arm ?CreateInstanceEnum@Provider@@AAAJPAVMethodContext@@J@Z() +;@ cdecl -arch=arm ?CreateInstanceEnumAsync@CWbemProviderGlue@@UAAJQAGJPAUIWbemContext@@PAUIWbemObjectSink@@@Z() +;@ cdecl -arch=arm ?CreateMsgProvider@CWinMsgEvent@@CAXXZ() +;@ cdecl -arch=arm ?CreateMsgWindow@CWinMsgEvent@@CAPAUHWND__@@XZ() +;@ cdecl -arch=arm ?CreateNewInstance@Provider@@IAAPAVCInstance@@PAVMethodContext@@@Z() +;@ cdecl -arch=arm ?CreateOpen@CRegistry@@QAAJPAUHKEY__@@PBGPAGKKPAU_SECURITY_ATTRIBUTES@@PAK@Z() +;@ cdecl -arch=arm ?CtrlHandlerRoutine@CWinMsgEvent@@CAHK@Z() +;@ cdecl -arch=arm ?DecrementMapCount@CWbemProviderGlue@@KAJPAJ@Z() +;@ cdecl -arch=arm ?DecrementMapCount@CWbemProviderGlue@@KAJPBVCWbemGlueFactory@@@Z() +;@ cdecl -arch=arm ?DecrementObjectCount@CWbemProviderGlue@@SAJXZ() +;@ cdecl -arch=arm ?DeleteClass@CWbemProviderGlue@@UAAJQAGJPAUIWbemContext@@PAPAUIWbemCallResult@@@Z() +;@ cdecl -arch=arm ?DeleteClassAsync@CWbemProviderGlue@@UAAJQAGJPAUIWbemContext@@PAUIWbemObjectSink@@@Z() +;@ cdecl -arch=arm ?DeleteCurrentKeyValue@CRegistry@@QAAKPAUHKEY__@@PBG@Z() +;@ cdecl -arch=arm ?DeleteCurrentKeyValue@CRegistry@@QAAKPBG@Z() +;@ cdecl -arch=arm ?DeleteInstance@CWbemProviderGlue@@UAAJQAGJPAUIWbemContext@@PAPAUIWbemCallResult@@@Z() +;@ cdecl -arch=arm ?DeleteInstance@Provider@@AAAJPAUParsedObjectPath@@JPAVMethodContext@@@Z() +;@ cdecl -arch=arm ?DeleteInstance@Provider@@MAAJABVCInstance@@J@Z() +;@ cdecl -arch=arm ?DeleteInstanceAsync@CWbemProviderGlue@@UAAJQAGJPAUIWbemContext@@PAUIWbemObjectSink@@@Z() +;@ cdecl -arch=arm ?DeleteKey@CRegistry@@QAAJPAVCHString@@@Z() +;@ cdecl -arch=arm ?DeleteValue@CRegistry@@QAAJPBG@Z() +;@ cdecl -arch=arm ?Destroy@CWbemGlueFactory@@QAAXXZ() +;@ cdecl -arch=arm ?DestroyMsgWindow@CWinMsgEvent@@CAXXZ() +;@ cdecl -arch=arm ?ElementAt@CHPtrArray@@QAAAAPAXH@Z() +;@ cdecl -arch=arm ?ElementAt@CHStringArray@@QAAAAVCHString@@H@Z() +@ cdecl -arch=arm ?Empty@CHString@@QAAXXZ() +;@ cdecl -arch=arm ?Empty@CObjectPathParser@@AAAXXZ() +;@ cdecl -arch=arm ?EndRead@CThreadBase@@QAAXXZ() +;@ cdecl -arch=arm ?EndWrite@CThreadBase@@QAAXXZ() +;@ cdecl -arch=arm ?EnumerateAndGetValues@CRegistry@@QAAJAAKAAPAGAAPAE@Z() +;@ cdecl -arch=arm ?EnumerateInstances@Provider@@MAAJPAVMethodContext@@J@Z() +;@ cdecl -arch=arm ?ExecMethod@CWbemProviderGlue@@UAAJQAG0JPAUIWbemContext@@PAUIWbemClassObject@@PAPAU3@PAPAUIWbemCallResult@@@Z() +;@ cdecl -arch=arm ?ExecMethod@Provider@@AAAJPAUParsedObjectPath@@PAGJPAVCInstance@@2PAVMethodContext@@@Z() +;@ cdecl -arch=arm ?ExecMethod@Provider@@MAAJABVCInstance@@QAGPAV2@2J@Z() +;@ cdecl -arch=arm ?ExecMethodAsync@CWbemProviderGlue@@UAAJQAG0JPAUIWbemContext@@PAUIWbemClassObject@@PAUIWbemObjectSink@@@Z() +;@ cdecl -arch=arm ?ExecNotificationQuery@CWbemProviderGlue@@UAAJQAG0JPAUIWbemContext@@PAPAUIEnumWbemClassObject@@@Z() +;@ cdecl -arch=arm ?ExecNotificationQueryAsync@CWbemProviderGlue@@UAAJQAG0JPAUIWbemContext@@PAUIWbemObjectSink@@@Z() +;@ cdecl -arch=arm ?ExecQuery@CWbemProviderGlue@@UAAJQAG0JPAUIWbemContext@@PAPAUIEnumWbemClassObject@@@Z() +;@ cdecl -arch=arm ?ExecQuery@Provider@@MAAJPAVMethodContext@@AAVCFrameworkQuery@@J@Z() +;@ cdecl -arch=arm ?ExecQueryAsync@CWbemProviderGlue@@UAAJQAG0JPAUIWbemContext@@PAUIWbemObjectSink@@@Z() +;@ cdecl -arch=arm ?ExecuteQuery@Provider@@AAAJPAVMethodContext@@AAVCFrameworkQuery@@J@Z() +;@ cdecl -arch=arm ?FillInstance@CWbemProviderGlue@@SAJPAVCInstance@@PBG@Z() +;@ cdecl -arch=arm ?FillInstance@CWbemProviderGlue@@SAJPAVMethodContext@@PAVCInstance@@@Z() +@ cdecl -arch=arm ?Find@CHString@@QBAHG@Z() +@ cdecl -arch=arm ?Find@CHString@@QBAHPBG@Z() +@ cdecl -arch=arm ?FindOneOf@CHString@@QBAHPBG@Z() +@ cdecl -arch=arm ?Flush@Provider@@MAAXXZ() +;@ cdecl -arch=arm ?FlushAll@CWbemProviderGlue@@AAAXXZ() +@ cdecl -arch=arm ?Format@CHString@@QAAXIZZ() +@ cdecl -arch=arm ?Format@CHString@@QAAXPBGZZ() +@ cdecl -arch=arm ?FormatMessageW@CHString@@QAAXIZZ() +@ cdecl -arch=arm ?FormatMessageW@CHString@@QAAXPBGZZ() +@ cdecl -arch=arm ?FormatV@CHString@@QAAXPBGPAD@Z() +;@ cdecl -arch=arm ?FrameworkLogin@CWbemProviderGlue@@SAXPBGPAVProvider@@0@Z() +;@ cdecl -arch=arm ?FrameworkLoginDLL@CWbemProviderGlue@@SAHPBG@Z() +;@ cdecl -arch=arm ?FrameworkLoginDLL@CWbemProviderGlue@@SAHPBGPAJ@Z() +;@ cdecl -arch=arm ?FrameworkLogoff@CWbemProviderGlue@@SAXPBG0@Z() +;@ cdecl -arch=arm ?FrameworkLogoffDLL@CWbemProviderGlue@@SAHPBG@Z() +;@ cdecl -arch=arm ?FrameworkLogoffDLL@CWbemProviderGlue@@SAHPBGPAJ@Z() +;@ cdecl -arch=arm ?Free@CObjectPathParser@@QAAXPAUParsedObjectPath@@@Z() +;@ cdecl -arch=arm ?FreeExtra@CHPtrArray@@QAAXXZ() +@ cdecl -arch=arm ?FreeExtra@CHString@@QAAXXZ() +;@ cdecl -arch=arm ?FreeExtra@CHStringArray@@QAAXXZ() +;@ cdecl -arch=arm ?FreeSearchList@CRegistrySearch@@QAAHHAAVCHPtrArray@@@Z() +;@ cdecl -arch=arm ?GetAllDerivedInstances@CWbemProviderGlue@@SAJPBGPAV?$TRefPointerCollection@VCInstance@@@@PAVMethodContext@@0@Z() +;@ cdecl -arch=arm ?GetAllDerivedInstancesAsynch@CWbemProviderGlue@@SAJPBGPAVProvider@@P6AJ1PAVCInstance@@PAVMethodContext@@PAX@Z034@Z() +;@ cdecl -arch=arm ?GetAllInstances@CWbemProviderGlue@@SAJPBGPAV?$TRefPointerCollection@VCInstance@@@@0PAVMethodContext@@@Z() +;@ cdecl -arch=arm ?GetAllInstancesAsynch@CWbemProviderGlue@@SAJPBGPAVProvider@@P6AJ1PAVCInstance@@PAVMethodContext@@PAX@Z034@Z() +@ cdecl -arch=arm ?GetAllocLength@CHString@@QBAHXZ() +;@ cdecl -arch=arm ?GetAt@CHPtrArray@@QBAPAXH@Z() +@ cdecl -arch=arm ?GetAt@CHString@@QBAGH@Z() +;@ cdecl -arch=arm ?GetAt@CHStringArray@@QBA?AVCHString@@H@Z() +;@ cdecl -arch=arm ?GetBSTR@WBEMTime@@QBAPAGXZ() +;@ cdecl -arch=arm ?GetBSTR@WBEMTimeSpan@@QBAPAGXZ() +@ cdecl -arch=arm ?GetBuffer@CHString@@QAAPAGH@Z() +@ cdecl -arch=arm ?GetBufferSetLength@CHString@@QAAPAGH@Z() +;@ cdecl -arch=arm ?GetByte@CInstance@@QBA_NPBGAAE@Z() +;@ cdecl -arch=arm ?GetCHString@CInstance@@QBA_NPBGAAVCHString@@@Z() +;@ cdecl -arch=arm ?GetCSDVersion@CWbemProviderGlue@@SAPBGXZ() +;@ cdecl -arch=arm ?GetClassNameW@CRegistry@@QAAPAGXZ() +;@ cdecl -arch=arm ?GetClassObjectInterface@CInstance@@QAAPAUIWbemClassObject@@XZ() +;@ cdecl -arch=arm ?GetClassObjectInterface@Provider@@AAAPAUIWbemClassObject@@PAVMethodContext@@@Z() +;@ cdecl -arch=arm ?GetComputerNameW@CWbemProviderGlue@@CAXAAVCHString@@@Z() +;@ cdecl -arch=arm ?GetCurrentBinaryKeyValue@CRegistry@@QAAKPAUHKEY__@@PBGPAEPAK@Z() +;@ cdecl -arch=arm ?GetCurrentBinaryKeyValue@CRegistry@@QAAKPBGAAVCHString@@@Z() +;@ cdecl -arch=arm ?GetCurrentBinaryKeyValue@CRegistry@@QAAKPBGPAEPAK@Z() +;@ cdecl -arch=arm ?GetCurrentKeyValue@CRegistry@@QAAKPAUHKEY__@@PBGAAK@Z() +;@ cdecl -arch=arm ?GetCurrentKeyValue@CRegistry@@QAAKPAUHKEY__@@PBGAAVCHString@@@Z() +;@ cdecl -arch=arm ?GetCurrentKeyValue@CRegistry@@QAAKPAUHKEY__@@PBGAAVCHStringArray@@@Z() +;@ cdecl -arch=arm ?GetCurrentKeyValue@CRegistry@@QAAKPBGAAK@Z() +;@ cdecl -arch=arm ?GetCurrentKeyValue@CRegistry@@QAAKPBGAAVCHString@@@Z() +;@ cdecl -arch=arm ?GetCurrentKeyValue@CRegistry@@QAAKPBGAAVCHStringArray@@@Z() +;@ cdecl -arch=arm ?GetCurrentRawKeyValue@CRegistry@@AAAKPAUHKEY__@@PBGPAXPAK3@Z() +;@ cdecl -arch=arm ?GetCurrentRawSubKeyValue@CRegistry@@AAAKPBGPAXPAK2@Z() +;@ cdecl -arch=arm ?GetCurrentSubKeyCount@CRegistry@@QAAKXZ() +;@ cdecl -arch=arm ?GetCurrentSubKeyName@CRegistry@@QAAKAAVCHString@@@Z() +;@ cdecl -arch=arm ?GetCurrentSubKeyPath@CRegistry@@QAAKAAVCHString@@@Z() +;@ cdecl -arch=arm ?GetCurrentSubKeyValue@CRegistry@@QAAKPBGAAK@Z() +;@ cdecl -arch=arm ?GetCurrentSubKeyValue@CRegistry@@QAAKPBGAAVCHString@@@Z() +;@ cdecl -arch=arm ?GetCurrentSubKeyValue@CRegistry@@QAAKPBGPAXPAK@Z() +;@ cdecl -arch=arm ?GetDMTF@WBEMTime@@QBAPAGH@Z() +;@ cdecl -arch=arm ?GetDMTFNonNtfs@WBEMTime@@QBAPAGXZ() +;@ cdecl -arch=arm ?GetDOUBLE@CInstance@@QBA_NPBGAAN@Z() +;@ cdecl -arch=arm ?GetDWORD@CInstance@@QBA_NPBGAAK@Z() +;@ cdecl -arch=arm ?GetData@CHPtrArray@@QAAPAPAXXZ() +;@ cdecl -arch=arm ?GetData@CHPtrArray@@QBAPAPBXXZ() +@ cdecl -arch=arm ?GetData@CHString@@IBAPAUCHStringData@@XZ() +;@ cdecl -arch=arm ?GetData@CHStringArray@@QAAPAVCHString@@XZ() +;@ cdecl -arch=arm ?GetData@CHStringArray@@QBAPBVCHString@@XZ() +;@ cdecl -arch=arm ?GetDateTime@CInstance@@QBA_NPBGAAVWBEMTime@@@Z() +;@ cdecl -arch=arm ?GetEmbeddedObject@CInstance@@QBA_NPBGPAPAV1@PAVMethodContext@@@Z() +;@ cdecl -arch=arm ?GetEmptyInstance@CWbemProviderGlue@@SAJPAVMethodContext@@PBGPAPAVCInstance@@1@Z() +;@ cdecl -arch=arm ?GetEmptyInstance@CWbemProviderGlue@@SAJPBGPAPAVCInstance@@0@Z() +;@ cdecl -arch=arm ?GetFILETIME@WBEMTime@@QBAHPAU_FILETIME@@@Z() +;@ cdecl -arch=arm ?GetFILETIME@WBEMTimeSpan@@QBAHPAU_FILETIME@@@Z() +;@ cdecl -arch=arm ?GetIWBEMContext@MethodContext@@UAAPAUIWbemContext@@XZ() +;@ cdecl -arch=arm ?GetInstanceByPath@CWbemProviderGlue@@SAJPBGPAPAVCInstance@@PAVMethodContext@@@Z() +;@ cdecl -arch=arm ?GetInstanceFromCIMOM@CWbemProviderGlue@@CAJPBG0PAVMethodContext@@PAPAVCInstance@@@Z() +;@ cdecl -arch=arm ?GetInstanceKeysByPath@CWbemProviderGlue@@SAJPBGPAPAVCInstance@@PAVMethodContext@@@Z() +;@ cdecl -arch=arm ?GetInstancePropertiesByPath@CWbemProviderGlue@@SAJPBGPAPAVCInstance@@PAVMethodContext@@AAVCHStringArray@@@Z() +;@ cdecl -arch=arm ?GetInstancesByQuery@CWbemProviderGlue@@SAJPBGPAV?$TRefPointerCollection@VCInstance@@@@PAVMethodContext@@0@Z() +;@ cdecl -arch=arm ?GetInstancesByQueryAsynch@CWbemProviderGlue@@SAJPBGPAVProvider@@P6AJ1PAVCInstance@@PAVMethodContext@@PAX@Z034@Z() +;@ cdecl -arch=arm ?GetKeyString@ParsedObjectPath@@QAAPAGXZ() +@ cdecl -arch=arm ?GetLength@CHString@@QBAHXZ() +;@ cdecl -arch=arm ?GetLocalComputerName@Provider@@IAAABVCHString@@XZ() +;@ cdecl -arch=arm ?GetLocalInstancePath@Provider@@IAA_NPBVCInstance@@AAVCHString@@@Z() +;@ cdecl -arch=arm ?GetLocalOffsetForDate@WBEMTime@@SAJABJ@Z() +;@ cdecl -arch=arm ?GetLocalOffsetForDate@WBEMTime@@SAJPBU_FILETIME@@@Z() +;@ cdecl -arch=arm ?GetLocalOffsetForDate@WBEMTime@@SAJPBU_SYSTEMTIME@@@Z() +;@ cdecl -arch=arm ?GetLocalOffsetForDate@WBEMTime@@SAJPBUtm@@@Z() +;@ cdecl -arch=arm ?GetLongestClassStringSize@CRegistry@@QAAKXZ() +;@ cdecl -arch=arm ?GetLongestSubKeySize@CRegistry@@QAAKXZ() +;@ cdecl -arch=arm ?GetLongestValueData@CRegistry@@QAAKXZ() +;@ cdecl -arch=arm ?GetLongestValueName@CRegistry@@QAAKXZ() +;@ cdecl -arch=arm ?GetMapCountPtr@CWbemProviderGlue@@KAPAJPBVCWbemGlueFactory@@@Z() +;@ cdecl -arch=arm ?GetMethodContext@CInstance@@QBAPAVMethodContext@@XZ() +;@ cdecl -arch=arm ?GetNamespace@CFrameworkQuery@@IAAABVCHString@@XZ() +;@ cdecl -arch=arm ?GetNamespace@Provider@@IAAABVCHString@@XZ() +;@ cdecl -arch=arm ?GetNamespaceConnection@CWbemProviderGlue@@SAPAUIWbemServices@@PBG@Z() +;@ cdecl -arch=arm ?GetNamespaceConnection@CWbemProviderGlue@@SAPAUIWbemServices@@PBGPAVMethodContext@@@Z() +;@ cdecl -arch=arm ?GetNamespacePart@ParsedObjectPath@@QAAPAGXZ() +;@ cdecl -arch=arm ?GetOSMajorVersion@CWbemProviderGlue@@SAKXZ() +;@ cdecl -arch=arm ?GetObject@CWbemProviderGlue@@UAAJQAGJPAUIWbemContext@@PAPAUIWbemClassObject@@PAPAUIWbemCallResult@@@Z() +;@ cdecl -arch=arm ?GetObject@Provider@@AAAJPAUParsedObjectPath@@PAVMethodContext@@J@Z() +;@ cdecl -arch=arm ?GetObject@Provider@@MAAJPAVCInstance@@J@Z() +;@ cdecl -arch=arm ?GetObject@Provider@@MAAJPAVCInstance@@JAAVCFrameworkQuery@@@Z() +;@ cdecl -arch=arm ?GetObjectAsync@CWbemProviderGlue@@UAAJQAGJPAUIWbemContext@@PAUIWbemObjectSink@@@Z() +;@ cdecl -arch=arm ?GetParentNamespacePart@ParsedObjectPath@@QAAPAGXZ() +;@ cdecl -arch=arm ?GetPlatform@CWbemProviderGlue@@SAKXZ() +;@ cdecl -arch=arm ?GetPropertyBitMask@CFrameworkQueryEx@@QAAXABVCHPtrArray@@PAX@Z() +;@ cdecl -arch=arm ?GetProviderGlue@MethodContext@@AAAPAVCWbemProviderGlue@@XZ() +;@ cdecl -arch=arm ?GetProviderName@Provider@@IAAABVCHString@@XZ() +;@ cdecl -arch=arm ?GetQuery@CFrameworkQuery@@QAAABVCHString@@XZ() +;@ cdecl -arch=arm ?GetQueryClassName@CFrameworkQuery@@QAAPAGXZ() +;@ cdecl -arch=arm ?GetRelativePath@CObjectPathParser@@SAPAGPAG@Z() +;@ cdecl -arch=arm ?GetRequiredProperties@CFrameworkQuery@@QAAXAAVCHStringArray@@@Z() +;@ cdecl -arch=arm ?GetSYSTEMTIME@WBEMTime@@QBAHPAU_SYSTEMTIME@@@Z() +;@ cdecl -arch=arm ?GetSize@CHPtrArray@@QBAHXZ() +;@ cdecl -arch=arm ?GetSize@CHStringArray@@QBAHXZ() +;@ cdecl -arch=arm ?GetStatus@CInstance@@QBA_NPBGAA_NAAG@Z() +;@ cdecl -arch=arm ?GetStatusObject@CWbemProviderGlue@@CAPAUIWbemClassObject@@PAVMethodContext@@PBG@Z() +;@ cdecl -arch=arm ?GetStatusObject@MethodContext@@QAAPAUIWbemClassObject@@XZ() +;@ cdecl -arch=arm ?GetStringArray@CInstance@@QBA_NPBGAAPAUtagSAFEARRAY@@@Z() +;@ cdecl -arch=arm ?GetStructtm@WBEMTime@@QBAHPAUtm@@@Z() +;@ cdecl -arch=arm ?GetTime@WBEMTime@@QBA_KXZ() +;@ cdecl -arch=arm ?GetTime@WBEMTimeSpan@@QBA_KXZ() +;@ cdecl -arch=arm ?GetTimeSpan@CInstance@@QBA_NPBGAAVWBEMTimeSpan@@@Z() +;@ cdecl -arch=arm ?GetUpperBound@CHPtrArray@@QBAHXZ() +;@ cdecl -arch=arm ?GetUpperBound@CHStringArray@@QBAHXZ() +;@ cdecl -arch=arm ?GetValueCount@CRegistry@@QAAKXZ() +;@ cdecl -arch=arm ?GetValuesForProp@CFrameworkQuery@@QAAJPBGAAV?$vector@V_bstr_t@@V?$allocator@V_bstr_t@@@std@@@std@@@Z() +;@ cdecl -arch=arm ?GetValuesForProp@CFrameworkQuery@@QAAJPBGAAVCHStringArray@@@Z() +;@ cdecl -arch=arm ?GetValuesForProp@CFrameworkQueryEx@@QAAJPBGAAV?$vector@HV?$allocator@H@std@@@std@@@Z() +;@ cdecl -arch=arm ?GetValuesForProp@CFrameworkQueryEx@@QAAJPBGAAV?$vector@V_variant_t@@V?$allocator@V_variant_t@@@std@@@std@@@Z() +;@ cdecl -arch=arm ?GetVariant@CInstance@@QBA_NPBGAAUtagVARIANT@@@Z() +;@ cdecl -arch=arm ?GetWBEMINT16@CInstance@@QBA_NPBGAAF@Z() +;@ cdecl -arch=arm ?GetWBEMINT64@CInstance@@QBA_NPBGAAVCHString@@@Z() +;@ cdecl -arch=arm ?GetWBEMINT64@CInstance@@QBA_NPBGAA_J@Z() +;@ cdecl -arch=arm ?GetWBEMINT64@CInstance@@QBA_NPBGAA_K@Z() +;@ cdecl -arch=arm ?GetWCHAR@CInstance@@QBA_NPBGPAPAG@Z() +;@ cdecl -arch=arm ?GetWORD@CInstance@@QBA_NPBGAAG@Z() +;@ cdecl -arch=arm ?Getbool@CInstance@@QBA_NPBGAA_N@Z() +;@ cdecl -arch=arm ?GethKey@CRegistry@@QAAPAUHKEY__@@XZ() +;@ cdecl -arch=arm ?Gettime_t@WBEMTime@@QBAHPAJ@Z() +;@ cdecl -arch=arm ?Gettime_t@WBEMTimeSpan@@QBAHPAJ@Z() +;@ cdecl -arch=arm ?IncrementMapCount@CWbemProviderGlue@@KAJPAJ@Z() +;@ cdecl -arch=arm ?IncrementMapCount@CWbemProviderGlue@@KAJPBVCWbemGlueFactory@@@Z() +;@ cdecl -arch=arm ?IncrementObjectCount@CWbemProviderGlue@@SAXXZ() +;@ cdecl -arch=arm ?Init2@CFrameworkQuery@@QAAXPAUIWbemClassObject@@@Z() +;@ cdecl -arch=arm ?Init@CFrameworkQuery@@QAAJPAUParsedObjectPath@@PAUIWbemContext@@PBGAAVCHString@@@Z() +;@ cdecl -arch=arm ?Init@CFrameworkQuery@@QAAJQAG0JAAVCHString@@@Z() +@ cdecl -arch=arm ?Init@CHString@@IAAXXZ() +;@ cdecl -arch=arm ?Init@CWbemProviderGlue@@CAXXZ() +;@ cdecl -arch=arm ?InitComputerName@Provider@@CAXXZ() +;@ cdecl -arch=arm ?InitEx@CFrameworkQueryEx@@UAAJQAG0JAAVCHString@@@Z() +;@ cdecl -arch=arm ?Initialize@CWbemProviderGlue@@UAAJPAGJ00PAUIWbemServices@@PAUIWbemContext@@PAUIWbemProviderInitSink@@@Z() +;@ cdecl -arch=arm ?InsertAt@CHPtrArray@@QAAXHPAV1@@Z() +;@ cdecl -arch=arm ?InsertAt@CHPtrArray@@QAAXHPAXH@Z() +;@ cdecl -arch=arm ?InsertAt@CHStringArray@@QAAXHPAV1@@Z() +;@ cdecl -arch=arm ?InsertAt@CHStringArray@@QAAXHPBGH@Z() +;@ cdecl -arch=arm ?InternalGetNamespaceConnection@CWbemProviderGlue@@AAAPAUIWbemServices@@PBG@Z() +;@ cdecl -arch=arm ?Is3TokenOR@CFrameworkQueryEx@@QAAHPBG0AAUtagVARIANT@@1@Z() +;@ cdecl -arch=arm ?IsClass@ParsedObjectPath@@QAAHXZ() +;@ cdecl -arch=arm ?IsDerivedFrom@CWbemProviderGlue@@SA_NPBG0PAVMethodContext@@0@Z() +@ cdecl -arch=arm ?IsEmpty@CHString@@QBAHXZ() +;@ cdecl -arch=arm ?IsExtended@CFrameworkQueryEx@@UAA_NXZ() +;@ cdecl -arch=arm ?IsInList@CFrameworkQuery@@IAAKABVCHStringArray@@PBG@Z() +;@ cdecl -arch=arm ?IsInstance@ParsedObjectPath@@QAAHXZ() +;@ cdecl -arch=arm ?IsLocal@ParsedObjectPath@@QAAHPBG@Z() +;@ cdecl -arch=arm ?IsLoggingOn@ProviderLog@@QAA?AW4LogLevel@1@PAVCHString@@@Z() +;@ cdecl -arch=arm ?IsNTokenAnd@CFrameworkQueryEx@@QAAHAAVCHStringArray@@AAVCHPtrArray@@@Z() +;@ cdecl -arch=arm ?IsNull@CInstance@@QBA_NPBG@Z() +;@ cdecl -arch=arm ?IsObject@ParsedObjectPath@@QAAHXZ() +;@ cdecl -arch=arm ?IsOk@WBEMTime@@QBA_NXZ() +;@ cdecl -arch=arm ?IsOk@WBEMTimeSpan@@QBA_NXZ() +;@ cdecl -arch=arm ?IsPropertyRequired@CFrameworkQuery@@QAA_NPBG@Z() +;@ cdecl -arch=arm ?IsReference@CFrameworkQuery@@IAAHPBG@Z() +;@ cdecl -arch=arm ?IsRelative@ParsedObjectPath@@QAAHPBG0@Z() +;@ cdecl -arch=arm ?KeysOnly@CFrameworkQuery@@QAA_NXZ() +@ cdecl -arch=arm ?Left@CHString@@QBA?AV1@H@Z() +@ cdecl -arch=arm ?LoadStringW@CHString@@IAAHIPAGI@Z() +@ cdecl -arch=arm ?LoadStringW@CHString@@QAAHI@Z() +;@ cdecl -arch=arm ?LocalLogMessage@ProviderLog@@QAAXPBG0HW4LogLevel@1@@Z() +;@ cdecl -arch=arm ?LocalLogMessage@ProviderLog@@QAAXPBGHW4LogLevel@1@0ZZ() +;@ cdecl -arch=arm ?LocateKeyByNameOrValueName@CRegistrySearch@@QAAHPAUHKEY__@@PBG1PAPBGKAAVCHString@@3@Z() +;@ cdecl -arch=arm ?Lock@CThreadBase@@AAAXXZ() +@ cdecl -arch=arm ?LockBuffer@CHString@@QAAPAGXZ() +;@ cdecl -arch=arm ?LockFactoryMap@CWbemProviderGlue@@CAXXZ() +;@ cdecl -arch=arm ?LockProviderMap@CWbemProviderGlue@@CAXXZ() +;@ cdecl -arch=arm ?LockServer@CWbemGlueFactory@@UAAJH@Z() +;@ cdecl -arch=arm ?LogError@CInstance@@IBAXPBG00J@Z() +;@ cdecl -arch=arm ?MakeLocalPath@Provider@@IAA?AVCHString@@ABV2@@Z() +@ cdecl -arch=arm ?MakeLower@CHString@@QAAXXZ() +@ cdecl -arch=arm ?MakeReverse@CHString@@QAAXXZ() +@ cdecl -arch=arm ?MakeUpper@CHString@@QAAXXZ() +@ cdecl -arch=arm ?Mid@CHString@@QBA?AV1@H@Z() +@ cdecl -arch=arm ?Mid@CHString@@QBA?AV1@HH@Z() +;@ cdecl -arch=arm ?MsgWndProc@CWinMsgEvent@@CAJPAUHWND__@@IIJ@Z() +;@ cdecl -arch=arm ?NextSubKey@CRegistry@@QAAKXZ() +;@ cdecl -arch=arm ?NextToken@CObjectPathParser@@AAAHXZ() +;@ cdecl -arch=arm ?NormalizePath@@YAKPBG00KAAVCHString@@@Z() +;@ cdecl -arch=arm ?NullOutUnsetProperties@CWbemProviderGlue@@AAAJPAUIWbemClassObject@@PAPAU2@ABUtagVARIANT@@@Z() +;@ cdecl -arch=arm ?OnFinalRelease@CThreadBase@@MAAXXZ() +;@ cdecl -arch=arm ?Open@CRegistry@@QAAJPAUHKEY__@@PBGK@Z() +;@ cdecl -arch=arm ?OpenAndEnumerateSubKeys@CRegistry@@QAAJPAUHKEY__@@PBGK@Z() +;@ cdecl -arch=arm ?OpenCurrentUser@CRegistry@@QAAKPBGK@Z() +;@ cdecl -arch=arm ?OpenLocalMachineKeyAndReadValue@CRegistry@@QAAJPBG0AAVCHString@@@Z() +;@ cdecl -arch=arm ?OpenNamespace@CWbemProviderGlue@@UAAJQAGJPAUIWbemContext@@PAPAUIWbemServices@@PAPAUIWbemCallResult@@@Z() +;@ cdecl -arch=arm ?OpenSubKey@CRegistry@@AAAKXZ() +;@ cdecl -arch=arm ?Parse@CObjectPathParser@@QAAHPBGPAPAUParsedObjectPath@@@Z() +;@ cdecl -arch=arm ?PreProcessPutInstanceParms@CWbemProviderGlue@@AAAJPAUIWbemClassObject@@PAPAU2@PAUIWbemContext@@@Z() +;@ cdecl -arch=arm ?PrepareToReOpen@CRegistry@@AAAXXZ() +;@ cdecl -arch=arm ?PutClass@CWbemProviderGlue@@UAAJPAUIWbemClassObject@@JPAUIWbemContext@@PAPAUIWbemCallResult@@@Z() +;@ cdecl -arch=arm ?PutClassAsync@CWbemProviderGlue@@UAAJPAUIWbemClassObject@@JPAUIWbemContext@@PAUIWbemObjectSink@@@Z() +;@ cdecl -arch=arm ?PutInstance@CWbemProviderGlue@@UAAJPAUIWbemClassObject@@JPAUIWbemContext@@PAPAUIWbemCallResult@@@Z() +;@ cdecl -arch=arm ?PutInstance@Provider@@AAAJPAUIWbemClassObject@@JPAVMethodContext@@@Z() +;@ cdecl -arch=arm ?PutInstance@Provider@@MAAJABVCInstance@@J@Z() +;@ cdecl -arch=arm ?PutInstanceAsync@CWbemProviderGlue@@UAAJPAUIWbemClassObject@@JPAUIWbemContext@@PAUIWbemObjectSink@@@Z() +;@ cdecl -arch=arm ?QueryInterface@CWbemGlueFactory@@UAAJABU_GUID@@PAPAX@Z() +;@ cdecl -arch=arm ?QueryInterface@CWbemProviderGlue@@UAAJABU_GUID@@PAPAX@Z() +;@ cdecl -arch=arm ?QueryObjectSink@CWbemProviderGlue@@UAAJJPAPAUIWbemObjectSink@@@Z() +;@ cdecl -arch=arm ?QueryPostProcess@MethodContext@@UAAXXZ() +;@ cdecl -arch=arm ?RegisterForMessage@CWinMsgEvent@@IAAXIH@Z() +# @ cdecl -arch=arm ?Release@CHString@@QAAXXZ() # FIXME! +# @ cdecl -arch=arm ?Release@CHString@@SAXPAUCHStringData@@@Z() # FIXME! +;@ cdecl -arch=arm ?Release@CInstance@@QAAJXZ() +;@ cdecl -arch=arm ?Release@CThreadBase@@QAAJXZ() +;@ cdecl -arch=arm ?Release@CWbemGlueFactory@@UAAKXZ() +;@ cdecl -arch=arm ?Release@CWbemProviderGlue@@UAAKXZ() +;@ cdecl -arch=arm ?Release@MethodContext@@QAAJXZ() +@ cdecl -arch=arm ?ReleaseBuffer@CHString@@QAAXH@Z() +;@ cdecl -arch=arm ?RemoveAll@CHPtrArray@@QAAXXZ() +;@ cdecl -arch=arm ?RemoveAll@CHStringArray@@QAAXXZ() +;@ cdecl -arch=arm ?RemoveAt@CHPtrArray@@QAAXHH@Z() +;@ cdecl -arch=arm ?RemoveAt@CHStringArray@@QAAXHH@Z() +;@ cdecl -arch=arm ?RemoveFromFactoryMap@CWbemProviderGlue@@KAXPBVCWbemGlueFactory@@@Z() +;@ cdecl -arch=arm ?Reset@CFrameworkQuery@@AAAXXZ() +@ cdecl -arch=arm ?ReverseFind@CHString@@QBAHG@Z() +;@ cdecl -arch=arm ?RewindSubKeys@CRegistry@@QAAXXZ() +@ cdecl -arch=arm ?Right@CHString@@QBA?AV1@H@Z() +@ cdecl -arch=arm ?SafeStrlen@CHString@@KAHPBG@Z() +;@ cdecl -arch=arm ?SearchAndBuildList@CRegistrySearch@@QAAHVCHString@@AAVCHPtrArray@@00HPAUHKEY__@@@Z() +;@ cdecl -arch=arm ?SearchMapForProvider@CWbemProviderGlue@@CAPAVProvider@@PBG0@Z() +;@ cdecl -arch=arm ?SetAt@CHPtrArray@@QAAXHPAX@Z() +@ cdecl -arch=arm ?SetAt@CHString@@QAAXHG@Z() +;@ cdecl -arch=arm ?SetAt@CHStringArray@@QAAXHPBG@Z() +;@ cdecl -arch=arm ?SetAtGrow@CHPtrArray@@QAAXHPAX@Z() +;@ cdecl -arch=arm ?SetAtGrow@CHStringArray@@QAAXHPBG@Z() +;@ cdecl -arch=arm ?SetByte@CInstance@@QAA_NPBGE@Z() +;@ cdecl -arch=arm ?SetCHString@CInstance@@QAA_NPBG0@Z() +;@ cdecl -arch=arm ?SetCHString@CInstance@@QAA_NPBGABVCHString@@@Z() +;@ cdecl -arch=arm ?SetCHString@CInstance@@QAA_NPBGPBD@Z() +;@ cdecl -arch=arm ?SetCHStringResourceHandle@@YAXPAUHINSTANCE__@@@Z() +;@ cdecl -arch=arm ?SetCharSplat@CInstance@@QAA_NPBG0@Z() +;@ cdecl -arch=arm ?SetCharSplat@CInstance@@QAA_NPBGK@Z() +;@ cdecl -arch=arm ?SetCharSplat@CInstance@@QAA_NPBGPBD@Z() +;@ cdecl -arch=arm ?SetClassName@ParsedObjectPath@@QAAHPBG@Z() +;@ cdecl -arch=arm ?SetCreationClassName@Provider@@IAA_NPAVCInstance@@@Z() +;@ cdecl -arch=arm ?SetCurrentKeyValue@CRegistry@@QAAKPAUHKEY__@@PBGAAK@Z() +;@ cdecl -arch=arm ?SetCurrentKeyValue@CRegistry@@QAAKPAUHKEY__@@PBGAAVCHString@@@Z() +;@ cdecl -arch=arm ?SetCurrentKeyValue@CRegistry@@QAAKPAUHKEY__@@PBGAAVCHStringArray@@@Z() +;@ cdecl -arch=arm ?SetCurrentKeyValue@CRegistry@@QAAKPBGAAK@Z() +;@ cdecl -arch=arm ?SetCurrentKeyValue@CRegistry@@QAAKPBGAAVCHString@@@Z() +;@ cdecl -arch=arm ?SetCurrentKeyValue@CRegistry@@QAAKPBGAAVCHStringArray@@@Z() +;@ cdecl -arch=arm ?SetCurrentKeyValueExpand@CRegistry@@QAAKPAUHKEY__@@PBGAAVCHString@@@Z() +;@ cdecl -arch=arm ?SetDMTF@WBEMTime@@QAAHQAG@Z() +;@ cdecl -arch=arm ?SetDOUBLE@CInstance@@QAA_NPBGN@Z() +;@ cdecl -arch=arm ?SetDWORD@CInstance@@QAA_NPBGK@Z() +;@ cdecl -arch=arm ?SetDateTime@CInstance@@QAA_NPBGABVWBEMTime@@@Z() +;@ cdecl -arch=arm ?SetDefaultValues@CRegistry@@AAAXXZ() +;@ cdecl -arch=arm ?SetEmbeddedObject@CInstance@@QAA_NPBGAAV1@@Z() +;@ cdecl -arch=arm ?SetKeyFromParsedObjectPath@Provider@@AAAHPAVCInstance@@PAUParsedObjectPath@@@Z() +;@ cdecl -arch=arm ?SetNull@CInstance@@QAA_NPBG@Z() +;@ cdecl -arch=arm ?SetPlatformID@CRegistry@@CAHXZ() +;@ cdecl -arch=arm ?SetSize@CHPtrArray@@QAAXHH@Z() +;@ cdecl -arch=arm ?SetSize@CHStringArray@@QAAXHH@Z() +;@ cdecl -arch=arm ?SetStatusObject@CWbemProviderGlue@@SA_NPAVMethodContext@@PBG1JPBUtagSAFEARRAY@@2@Z() +;@ cdecl -arch=arm ?SetStatusObject@MethodContext@@QAA_NPAUIWbemClassObject@@@Z() +;@ cdecl -arch=arm ?SetStringArray@CInstance@@QAA_NPBGABUtagSAFEARRAY@@@Z() +;@ cdecl -arch=arm ?SetTimeSpan@CInstance@@QAA_NPBGABVWBEMTimeSpan@@@Z() +;@ cdecl -arch=arm ?SetVariant@CInstance@@QAA_NPBGABUtagVARIANT@@@Z() +;@ cdecl -arch=arm ?SetWBEMINT16@CInstance@@QAA_NPBGABF@Z() +;@ cdecl -arch=arm ?SetWBEMINT64@CInstance@@QAA_NPBGABVCHString@@@Z() +;@ cdecl -arch=arm ?SetWBEMINT64@CInstance@@QAA_NPBG_J@Z() +;@ cdecl -arch=arm ?SetWBEMINT64@CInstance@@QAA_NPBG_K@Z() +;@ cdecl -arch=arm ?SetWCHARSplat@CInstance@@QAA_NPBG0@Z() +;@ cdecl -arch=arm ?SetWORD@CInstance@@QAA_NPBGG@Z() +;@ cdecl -arch=arm ?Setbool@CInstance@@QAA_NPBG_N@Z() +;@ cdecl -arch=arm ?Signal@CAutoEvent@@QAAHXZ() +@ cdecl -arch=arm ?SpanExcluding@CHString@@QBA?AV1@PBG@Z() +@ cdecl -arch=arm ?SpanIncluding@CHString@@QBA?AV1@PBG@Z() +@ cdecl -arch=arm ?TrimLeft@CHString@@QAAXXZ() +@ cdecl -arch=arm ?TrimRight@CHString@@QAAXXZ() +;@ cdecl -arch=arm ?UnInit@CWbemProviderGlue@@CAXXZ() +;@ cdecl -arch=arm ?UnRegisterAllMessages@CWinMsgEvent@@IAAXXZ() +;@ cdecl -arch=arm ?UnRegisterMessage@CWinMsgEvent@@IAA_NIH@Z() +;@ cdecl -arch=arm ?Unlock@CThreadBase@@AAAXXZ() +@ cdecl -arch=arm ?UnlockBuffer@CHString@@QAAXXZ() +;@ cdecl -arch=arm ?UnlockFactoryMap@CWbemProviderGlue@@CAXXZ() +;@ cdecl -arch=arm ?UnlockProviderMap@CWbemProviderGlue@@CAXXZ() +;@ cdecl -arch=arm ?Unparse@CObjectPathParser@@SAHPAUParsedObjectPath@@PAPAG@Z() +@ cdecl -arch=arm ?ValidateDeletionFlags@Provider@@MAAJJ@Z() +;@ cdecl -arch=arm ?ValidateEnumerationFlags@Provider@@MAAJJ@Z() +;@ cdecl -arch=arm ?ValidateFlags@Provider@@IAAJJW4FlagDefs@1@@Z() +;@ cdecl -arch=arm ?ValidateGetObjFlags@Provider@@MAAJJ@Z() +;@ cdecl -arch=arm ?ValidateIMOSPointer@Provider@@AAAHXZ() +@ cdecl -arch=arm ?ValidateMethodFlags@Provider@@MAAJJ@Z() +;@ cdecl -arch=arm ?ValidatePutInstanceFlags@Provider@@MAAJJ@Z() +@ cdecl -arch=arm ?ValidateQueryFlags@Provider@@MAAJJ@Z() +;@ cdecl -arch=arm ?Wait@CAutoEvent@@QAAKK@Z() +;@ cdecl -arch=arm ?WindowsDispatch@CWinMsgEvent@@CAXXZ() +;@ cdecl -arch=arm ?Zero@CObjectPathParser@@AAAXXZ() +;@ cdecl -arch=arm ?begin_parse@CObjectPathParser@@AAAHXZ() +;@ extern -arch=arm ?captainsLog@@3VProviderLog@@A +;@ cdecl -arch=arm ?dwThreadProc@CWinMsgEvent@@CAKPAX@Z() +;@ extern -arch=arm ?g_cs@@3VCCritSec@@A +;@ cdecl -arch=arm ?ident_becomes_class@CObjectPathParser@@AAAHXZ() +;@ cdecl -arch=arm ?ident_becomes_ns@CObjectPathParser@@AAAHXZ() +;@ cdecl -arch=arm ?initFailed@Provider@@SAHXZ() +;@ extern -arch=arm ?initFailed_@Provider@@0HA +;@ cdecl -arch=arm ?key_const@CObjectPathParser@@AAAHXZ() +;@ cdecl -arch=arm ?keyref@CObjectPathParser@@AAAHXZ() +;@ cdecl -arch=arm ?keyref_list@CObjectPathParser@@AAAHXZ() +;@ cdecl -arch=arm ?keyref_term@CObjectPathParser@@AAAHXZ() +;@ extern -arch=arm ?m_FlushPtrs@CWbemProviderGlue@@0V?$set@PAXU?$less@PAX@std@@V?$allocator@PAX@2@@std@@A +;@ extern -arch=arm ?m_csFlushPtrs@CWbemProviderGlue@@0VCCritSec@@A +;@ extern -arch=arm ?m_csStatusObject@CWbemProviderGlue@@0VCCritSec@@A +;@ extern -arch=arm ?m_pStatusObject@CWbemProviderGlue@@0PAUIWbemClassObject@@A +;@ extern -arch=arm ?mg_aeCreateWindow@CWinMsgEvent@@0VCAutoEvent@@A +;@ extern -arch=arm ?mg_csMapLock@CWinMsgEvent@@0VCCritSec@@A +;@ extern -arch=arm ?mg_csWindowLock@CWinMsgEvent@@0VCCritSec@@A +;@ extern -arch=arm ?mg_hDevNotify@CWinMsgEvent@@0PAXA +;@ extern -arch=arm ?mg_hThreadPumpHandle@CWinMsgEvent@@0PAXA +;@ extern -arch=arm ?mg_hWnd@CWinMsgEvent@@0PAUHWND__@@A +;@ extern -arch=arm ?mg_oSinkMap@CWinMsgEvent@@0V?$multimap@IPAVCWinMsgEvent@@U?$less@I@std@@V?$allocator@PAVCWinMsgEvent@@@3@@std@@A +;@ cdecl -arch=arm ?myRegCreateKeyEx@CRegistry@@AAAJPAUHKEY__@@PBGKPAGKKQAU_SECURITY_ATTRIBUTES@@PAPAU2@PAK@Z() +;@ cdecl -arch=arm ?myRegDeleteKey@CRegistry@@AAAJPAUHKEY__@@PBG@Z() +;@ cdecl -arch=arm ?myRegDeleteValue@CRegistry@@AAAJPAUHKEY__@@PBG@Z() +;@ cdecl -arch=arm ?myRegEnumKey@CRegistry@@AAAJPAUHKEY__@@KPAGK@Z() +;@ cdecl -arch=arm ?myRegEnumValue@CRegistry@@AAAJPAUHKEY__@@KPAGPAK22PAE2@Z() +;@ cdecl -arch=arm ?myRegOpenKeyEx@CRegistry@@AAAJPAUHKEY__@@PBGKKPAPAU2@@Z() +;@ cdecl -arch=arm ?myRegQueryInfoKey@CRegistry@@AAAJPAUHKEY__@@PAGPAK22222222PAU_FILETIME@@@Z() +;@ cdecl -arch=arm ?myRegQueryValueEx@CRegistry@@AAAJPAUHKEY__@@PBGPAK2PAE2@Z() +;@ cdecl -arch=arm ?myRegSetValueEx@CRegistry@@AAAJPAUHKEY__@@PBGKKPBEK@Z() +;@ cdecl -arch=arm ?ns_list@CObjectPathParser@@AAAHXZ() +;@ cdecl -arch=arm ?ns_list_rest@CObjectPathParser@@AAAHXZ() +;@ cdecl -arch=arm ?ns_or_class@CObjectPathParser@@AAAHXZ() +;@ cdecl -arch=arm ?ns_or_server@CObjectPathParser@@AAAHXZ() +;@ cdecl -arch=arm ?objref@CObjectPathParser@@AAAHXZ() +;@ cdecl -arch=arm ?objref_rest@CObjectPathParser@@AAAHXZ() +;@ cdecl -arch=arm ?optional_objref@CObjectPathParser@@AAAHXZ() +;@ cdecl -arch=arm ?propname@CObjectPathParser@@AAAHXZ() +;@ extern -arch=arm ?s_bInitted@CWbemProviderGlue@@0HA +;@ extern -arch=arm ?s_csFactoryMap@CWbemProviderGlue@@0VCCritSec@@A +;@ extern -arch=arm ?s_csProviderMap@CWbemProviderGlue@@0VCCritSec@@A +;@ extern -arch=arm ?s_dwMajorVersion@CWbemProviderGlue@@0KA +;@ extern -arch=arm ?s_dwPlatform@CRegistry@@0KA +;@ extern -arch=arm ?s_dwPlatform@CWbemProviderGlue@@0KA +;@ extern -arch=arm ?s_fPlatformSet@CRegistry@@0HA +;@ extern -arch=arm ?s_factorymap@CWbemProviderGlue@@0V?$map@PBXPAJU?$less@PBX@std@@V?$allocator@PAJ@2@@std@@A +;@ extern -arch=arm ?s_lObjects@CWbemProviderGlue@@0JA +;@ extern -arch=arm ?s_providersmap@CWbemProviderGlue@@0V?$map@VCHString@@PAXU?$less@VCHString@@@std@@V?$allocator@PAX@3@@std@@A +;@ extern -arch=arm ?s_strComputerName@Provider@@0VCHString@@A +;@ extern -arch=arm ?s_wstrCSDVersion@CWbemProviderGlue@@0PAGA +;@ cdecl -arch=arm DoCmd() diff --git a/reactos/dll/win32/framedyn/main.c b/reactos/dll/win32/framedyn/main.c new file mode 100644 index 00000000000..a815809ab34 --- /dev/null +++ b/reactos/dll/win32/framedyn/main.c @@ -0,0 +1,29 @@ +/* + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS system libraries + * FILE: dll/win32/framedyn/main.c + * PURPOSE: framedyn entry point + * PROGRAMMERS: Pierre Schweitzer (pierre@reactos.org) + * + */ + +/* INCLUDES ******************************************************************/ + +#include +#include +#include + +BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) +{ + + switch (fdwReason) + { + case DLL_PROCESS_ATTACH: + DisableThreadLibraryCalls(hinstDLL); + break; + case DLL_PROCESS_DETACH: + break; + } + + return TRUE; +} diff --git a/reactos/dll/win32/framedyn/provider.cpp b/reactos/dll/win32/framedyn/provider.cpp new file mode 100644 index 00000000000..7eeb810d2b1 --- /dev/null +++ b/reactos/dll/win32/framedyn/provider.cpp @@ -0,0 +1,57 @@ +/* + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS system libraries + * FILE: dll/win32/framedyn/provider.cpp + * PURPOSE: Provider class implementation + * PROGRAMMERS: Pierre Schweitzer (pierre@reactos.org) + */ + +/* INCLUDES ******************************************************************/ + +#include +#include +#define NDEBUG +#include + +/* PUBLIC FUNCTIONS **********************************************************/ + +/* + * @unimplemented + */ +void Provider::Flush() +{ + return; +} + +/* + * @implemented + */ +HRESULT Provider::ValidateDeletionFlags(long lFlags) +{ + if (lFlags == 0) + return WBEM_S_NO_ERROR; + + return WBEM_E_UNSUPPORTED_PARAMETER; +} + +/* + * @implemented + */ +HRESULT Provider::ValidateMethodFlags(long lFlags) +{ + if (lFlags == 0) + return WBEM_S_NO_ERROR; + + return WBEM_E_UNSUPPORTED_PARAMETER; +} + +/* + * @implemented + */ +HRESULT Provider::ValidateQueryFlags(long lFlags) +{ + if (lFlags == 0) + return WBEM_S_NO_ERROR; + + return WBEM_E_UNSUPPORTED_PARAMETER; +} diff --git a/reactos/dll/win32/wbemdisp/CMakeLists.txt b/reactos/dll/win32/wbemdisp/CMakeLists.txt new file mode 100644 index 00000000000..c4493130196 --- /dev/null +++ b/reactos/dll/win32/wbemdisp/CMakeLists.txt @@ -0,0 +1,32 @@ + +add_definitions(-D__WINESRC__) +include_directories(${REACTOS_SOURCE_DIR}/sdk/include/reactos/wine) +spec2def(wbemdisp.dll wbemdisp.spec) + +list(APPEND SOURCE + locator.c + main.c + wbemdisp_private.h) + +add_idl_headers(wbemdisp_idlheader wbemdisp_classes.idl) +add_typelib(wbemdisp_tlb.idl) + +list(APPEND wbemdisp_rc_deps + ${CMAKE_CURRENT_SOURCE_DIR}/wbemdisp_classes.rgs + ${CMAKE_CURRENT_SOURCE_DIR}/wbemdisp_tlb.rgs + ${CMAKE_CURRENT_BINARY_DIR}/wbemdisp_tlb.tlb) + +set_source_files_properties(wbemdisp.rc PROPERTIES OBJECT_DEPENDS "${wbemdisp_rc_deps}") + +add_library(wbemdisp SHARED + ${SOURCE} + guid.c + wbemdisp.rc + ${CMAKE_CURRENT_BINARY_DIR}/wbemdisp.def) + +set_module_type(wbemdisp win32dll) +target_link_libraries(wbemdisp uuid wine) +add_dependencies(wbemdisp stdole2 wbemdisp_idlheader) +add_importlibs(wbemdisp oleaut32 ole32 msvcrt kernel32 ntdll) +add_pch(wbemdisp wbemdisp_private.h SOURCE) +add_cd_file(TARGET wbemdisp DESTINATION reactos/system32/wbem FOR all) diff --git a/reactos/dll/win32/wbemdisp/guid.c b/reactos/dll/win32/wbemdisp/guid.c new file mode 100644 index 00000000000..2ac85248c53 --- /dev/null +++ b/reactos/dll/win32/wbemdisp/guid.c @@ -0,0 +1,18 @@ +/* DO NOT USE THE PRECOMPILED HEADER FOR THIS FILE! */ + +#include + +#define WIN32_NO_STATUS +#define _INC_WINDOWS +#define COM_NO_WINDOWS_H + +#include +#include +#include +#include +#include +#include +#include +#include + +/* NO CODE HERE, THIS IS JUST REQUIRED FOR THE GUID DEFINITIONS */ diff --git a/reactos/dll/win32/wbemdisp/locator.c b/reactos/dll/win32/wbemdisp/locator.c new file mode 100644 index 00000000000..28277795c99 --- /dev/null +++ b/reactos/dll/win32/wbemdisp/locator.c @@ -0,0 +1,1658 @@ +/* + * Copyright 2013 Hans Leidekker for CodeWeavers + * + * 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 "wbemdisp_private.h" + +#include + +static HRESULT EnumVARIANT_create( IEnumWbemClassObject *, IEnumVARIANT ** ); +static HRESULT ISWbemSecurity_create( ISWbemSecurity ** ); + +enum type_id +{ + ISWbemLocator_tid, + ISWbemObject_tid, + ISWbemObjectSet_tid, + ISWbemServices_tid, + ISWbemSecurity_tid, + last_tid +}; + +static ITypeLib *wbemdisp_typelib; +static ITypeInfo *wbemdisp_typeinfo[last_tid]; + +static REFIID wbemdisp_tid_id[] = +{ + &IID_ISWbemLocator, + &IID_ISWbemObject, + &IID_ISWbemObjectSet, + &IID_ISWbemServices, + &IID_ISWbemSecurity +}; + +static HRESULT get_typeinfo( enum type_id tid, ITypeInfo **ret ) +{ + HRESULT hr; + + if (!wbemdisp_typelib) + { + ITypeLib *typelib; + + hr = LoadRegTypeLib( &LIBID_WbemScripting, 1, 2, LOCALE_SYSTEM_DEFAULT, &typelib ); + if (FAILED( hr )) + { + ERR( "LoadRegTypeLib failed: %08x\n", hr ); + return hr; + } + if (InterlockedCompareExchangePointer( (void **)&wbemdisp_typelib, typelib, NULL )) + ITypeLib_Release( typelib ); + } + if (!wbemdisp_typeinfo[tid]) + { + ITypeInfo *typeinfo; + + hr = ITypeLib_GetTypeInfoOfGuid( wbemdisp_typelib, wbemdisp_tid_id[tid], &typeinfo ); + if (FAILED( hr )) + { + ERR( "GetTypeInfoOfGuid(%s) failed: %08x\n", debugstr_guid(wbemdisp_tid_id[tid]), hr ); + return hr; + } + if (InterlockedCompareExchangePointer( (void **)(wbemdisp_typeinfo + tid), typeinfo, NULL )) + ITypeInfo_Release( typeinfo ); + } + *ret = wbemdisp_typeinfo[tid]; + ITypeInfo_AddRef( *ret ); + return S_OK; +} + +#define DISPID_BASE 0x1800000 + +struct member +{ + BSTR name; + DISPID dispid; +}; + +struct object +{ + ISWbemObject ISWbemObject_iface; + LONG refs; + IWbemClassObject *object; + struct member *members; + UINT nb_members; + DISPID last_dispid; +}; + +static inline struct object *impl_from_ISWbemObject( + ISWbemObject *iface ) +{ + return CONTAINING_RECORD( iface, struct object, ISWbemObject_iface ); +} + +static ULONG WINAPI object_AddRef( + ISWbemObject *iface ) +{ + struct object *object = impl_from_ISWbemObject( iface ); + return InterlockedIncrement( &object->refs ); +} + +static ULONG WINAPI object_Release( + ISWbemObject *iface ) +{ + struct object *object = impl_from_ISWbemObject( iface ); + LONG refs = InterlockedDecrement( &object->refs ); + if (!refs) + { + UINT i; + + TRACE( "destroying %p\n", object ); + IWbemClassObject_Release( object->object ); + for (i = 0; i < object->nb_members; i++) SysFreeString( object->members[i].name ); + heap_free( object->members ); + heap_free( object ); + } + return refs; +} + +static HRESULT WINAPI object_QueryInterface( + ISWbemObject *iface, + REFIID riid, + void **ppvObject ) +{ + struct object *object = impl_from_ISWbemObject( iface ); + + TRACE( "%p %s %p\n", object, debugstr_guid(riid), ppvObject ); + + if (IsEqualGUID( riid, &IID_ISWbemObject ) || + IsEqualGUID( riid, &IID_IDispatch ) || + IsEqualGUID( riid, &IID_IUnknown )) + { + *ppvObject = object; + } + else + { + FIXME( "interface %s not implemented\n", debugstr_guid(riid) ); + return E_NOINTERFACE; + } + ISWbemObject_AddRef( iface ); + return S_OK; +} + +static HRESULT WINAPI object_GetTypeInfoCount( + ISWbemObject *iface, + UINT *count ) +{ + struct object *object = impl_from_ISWbemObject( iface ); + + TRACE( "%p, %p\n", object, count ); + *count = 1; + return S_OK; +} + +static HRESULT WINAPI object_GetTypeInfo( + ISWbemObject *iface, + UINT index, + LCID lcid, + ITypeInfo **info ) +{ + struct object *object = impl_from_ISWbemObject( iface ); + FIXME( "%p, %u, %u, %p\n", object, index, lcid, info ); + return E_NOTIMPL; +} + +#define DISPID_BASE 0x1800000 + +static HRESULT init_members( struct object *object ) +{ + LONG bound, i; + SAFEARRAY *sa; + HRESULT hr; + + if (object->members) return S_OK; + + hr = IWbemClassObject_GetNames( object->object, NULL, 0, NULL, &sa ); + if (FAILED( hr )) return hr; + hr = SafeArrayGetUBound( sa, 1, &bound ); + if (FAILED( hr )) + { + SafeArrayDestroy( sa ); + return hr; + } + if (!(object->members = heap_alloc( sizeof(struct member) * (bound + 1) ))) + { + SafeArrayDestroy( sa ); + return E_OUTOFMEMORY; + } + for (i = 0; i <= bound; i++) + { + hr = SafeArrayGetElement( sa, &i, &object->members[i].name ); + if (FAILED( hr )) + { + for (i--; i >= 0; i--) SysFreeString( object->members[i].name ); + SafeArrayDestroy( sa ); + heap_free( object->members ); + object->members = NULL; + return E_OUTOFMEMORY; + } + object->members[i].dispid = 0; + } + object->nb_members = bound + 1; + SafeArrayDestroy( sa ); + return S_OK; +} + +static DISPID get_member_dispid( struct object *object, const WCHAR *name ) +{ + UINT i; + for (i = 0; i < object->nb_members; i++) + { + if (!strcmpiW( object->members[i].name, name )) + { + if (!object->members[i].dispid) object->members[i].dispid = ++object->last_dispid; + return object->members[i].dispid; + } + } + return DISPID_UNKNOWN; +} + +static HRESULT WINAPI object_GetIDsOfNames( + ISWbemObject *iface, + REFIID riid, + LPOLESTR *names, + UINT count, + LCID lcid, + DISPID *dispid ) +{ + struct object *object = impl_from_ISWbemObject( iface ); + HRESULT hr; + UINT i; + + TRACE( "%p, %s, %p, %u, %u, %p\n", object, debugstr_guid(riid), names, count, lcid, dispid ); + + if (!names || !count || !dispid) return E_INVALIDARG; + + hr = init_members( object ); + if (FAILED( hr )) return hr; + + for (i = 0; i < count; i++) + { + if ((dispid[i] = get_member_dispid( object, names[i] )) == DISPID_UNKNOWN) break; + } + if (i != count) return DISP_E_UNKNOWNNAME; + return S_OK; +} + +static BSTR get_member_name( struct object *object, DISPID dispid ) +{ + UINT i; + for (i = 0; i < object->nb_members; i++) + { + if (object->members[i].dispid == dispid) return object->members[i].name; + } + return NULL; +} + +static HRESULT WINAPI object_Invoke( + ISWbemObject *iface, + DISPID member, + REFIID riid, + LCID lcid, + WORD flags, + DISPPARAMS *params, + VARIANT *result, + EXCEPINFO *excep_info, + UINT *arg_err ) +{ + struct object *object = impl_from_ISWbemObject( iface ); + BSTR name; + + TRACE( "%p, %x, %s, %u, %x, %p, %p, %p, %p\n", object, member, debugstr_guid(riid), + lcid, flags, params, result, excep_info, arg_err ); + + if (flags != (DISPATCH_METHOD|DISPATCH_PROPERTYGET)) + { + FIXME( "flags %x not supported\n", flags ); + return E_NOTIMPL; + } + if (!(name = get_member_name( object, member ))) + return DISP_E_MEMBERNOTFOUND; + + memset( params, 0, sizeof(*params) ); + return IWbemClassObject_Get( object->object, name, 0, result, NULL, NULL ); +} + +static HRESULT WINAPI object_Put_( + ISWbemObject *iface, + LONG iFlags, + IDispatch *objWbemNamedValueSet, + ISWbemObjectPath **objWbemObjectPath ) +{ + FIXME( "\n" ); + return E_NOTIMPL; +} + +static const ISWbemObjectVtbl object_vtbl = +{ + object_QueryInterface, + object_AddRef, + object_Release, + object_GetTypeInfoCount, + object_GetTypeInfo, + object_GetIDsOfNames, + object_Invoke, + object_Put_ +}; + +static HRESULT SWbemObject_create( IWbemClassObject *wbem_object, ISWbemObject **obj ) +{ + struct object *object; + + TRACE( "%p, %p\n", obj, wbem_object ); + + if (!(object = heap_alloc( sizeof(*object) ))) return E_OUTOFMEMORY; + object->ISWbemObject_iface.lpVtbl = &object_vtbl; + object->refs = 1; + object->object = wbem_object; + IWbemClassObject_AddRef( object->object ); + object->members = NULL; + object->nb_members = 0; + object->last_dispid = DISPID_BASE; + + *obj = &object->ISWbemObject_iface; + TRACE( "returning iface %p\n", *obj ); + return S_OK; +} + +struct objectset +{ + ISWbemObjectSet ISWbemObjectSet_iface; + LONG refs; + IEnumWbemClassObject *objectenum; + LONG count; +}; + +static inline struct objectset *impl_from_ISWbemObjectSet( + ISWbemObjectSet *iface ) +{ + return CONTAINING_RECORD( iface, struct objectset, ISWbemObjectSet_iface ); +} + +static ULONG WINAPI objectset_AddRef( + ISWbemObjectSet *iface ) +{ + struct objectset *objectset = impl_from_ISWbemObjectSet( iface ); + return InterlockedIncrement( &objectset->refs ); +} + +static ULONG WINAPI objectset_Release( + ISWbemObjectSet *iface ) +{ + struct objectset *objectset = impl_from_ISWbemObjectSet( iface ); + LONG refs = InterlockedDecrement( &objectset->refs ); + if (!refs) + { + TRACE( "destroying %p\n", objectset ); + IEnumWbemClassObject_Release( objectset->objectenum ); + heap_free( objectset ); + } + return refs; +} + +static HRESULT WINAPI objectset_QueryInterface( + ISWbemObjectSet *iface, + REFIID riid, + void **ppvObject ) +{ + struct objectset *objectset = impl_from_ISWbemObjectSet( iface ); + + TRACE( "%p %s %p\n", objectset, debugstr_guid(riid), ppvObject ); + + if (IsEqualGUID( riid, &IID_ISWbemObjectSet ) || + IsEqualGUID( riid, &IID_IDispatch ) || + IsEqualGUID( riid, &IID_IUnknown )) + { + *ppvObject = objectset; + } + else + { + FIXME( "interface %s not implemented\n", debugstr_guid(riid) ); + return E_NOINTERFACE; + } + ISWbemObjectSet_AddRef( iface ); + return S_OK; +} + +static HRESULT WINAPI objectset_GetTypeInfoCount( + ISWbemObjectSet *iface, + UINT *count ) +{ + struct objectset *objectset = impl_from_ISWbemObjectSet( iface ); + TRACE( "%p, %p\n", objectset, count ); + *count = 1; + return S_OK; +} + +static HRESULT WINAPI objectset_GetTypeInfo( + ISWbemObjectSet *iface, + UINT index, + LCID lcid, + ITypeInfo **info ) +{ + struct objectset *objectset = impl_from_ISWbemObjectSet( iface ); + TRACE( "%p, %u, %u, %p\n", objectset, index, lcid, info ); + + return get_typeinfo( ISWbemObjectSet_tid, info ); +} + +static HRESULT WINAPI objectset_GetIDsOfNames( + ISWbemObjectSet *iface, + REFIID riid, + LPOLESTR *names, + UINT count, + LCID lcid, + DISPID *dispid ) +{ + struct objectset *objectset = impl_from_ISWbemObjectSet( iface ); + ITypeInfo *typeinfo; + HRESULT hr; + + TRACE( "%p, %s, %p, %u, %u, %p\n", objectset, debugstr_guid(riid), names, count, lcid, dispid ); + + if (!names || !count || !dispid) return E_INVALIDARG; + + hr = get_typeinfo( ISWbemObjectSet_tid, &typeinfo ); + if (SUCCEEDED(hr)) + { + hr = ITypeInfo_GetIDsOfNames( typeinfo, names, count, dispid ); + ITypeInfo_Release( typeinfo ); + } + return hr; +} + +static HRESULT WINAPI objectset_Invoke( + ISWbemObjectSet *iface, + DISPID member, + REFIID riid, + LCID lcid, + WORD flags, + DISPPARAMS *params, + VARIANT *result, + EXCEPINFO *excep_info, + UINT *arg_err ) +{ + struct objectset *objectset = impl_from_ISWbemObjectSet( iface ); + ITypeInfo *typeinfo; + HRESULT hr; + + TRACE( "%p, %d, %s, %d, %d, %p, %p, %p, %p\n", objectset, member, debugstr_guid(riid), + lcid, flags, params, result, excep_info, arg_err ); + + hr = get_typeinfo( ISWbemObjectSet_tid, &typeinfo ); + if (SUCCEEDED(hr)) + { + hr = ITypeInfo_Invoke( typeinfo, &objectset->ISWbemObjectSet_iface, member, flags, + params, result, excep_info, arg_err ); + ITypeInfo_Release( typeinfo ); + } + return hr; +} + +static HRESULT WINAPI objectset_get__NewEnum( + ISWbemObjectSet *iface, + IUnknown **pUnk ) +{ + struct objectset *objectset = impl_from_ISWbemObjectSet( iface ); + IEnumWbemClassObject *objectenum; + HRESULT hr; + + TRACE( "%p, %p\n", objectset, pUnk ); + + hr = IEnumWbemClassObject_Clone( objectset->objectenum, &objectenum ); + if (FAILED( hr )) return hr; + + hr = EnumVARIANT_create( objectenum, (IEnumVARIANT **)pUnk ); + IEnumWbemClassObject_Release( objectenum ); + return hr; +} + +static HRESULT WINAPI objectset_Item( + ISWbemObjectSet *iface, + BSTR strObjectPath, + LONG iFlags, + ISWbemObject **objWbemObject ) +{ + FIXME( "\n" ); + return E_NOTIMPL; +} + +static HRESULT WINAPI objectset_get_Count( + ISWbemObjectSet *iface, + LONG *iCount ) +{ + struct objectset *objectset = impl_from_ISWbemObjectSet( iface ); + + TRACE( "%p, %p\n", objectset, iCount ); + + *iCount = objectset->count; + return S_OK; +} + +static HRESULT WINAPI objectset_get_Security_( + ISWbemObjectSet *iface, + ISWbemSecurity **objWbemSecurity ) +{ + FIXME( "\n" ); + return E_NOTIMPL; +} + +static HRESULT WINAPI objectset_ItemIndex( + ISWbemObjectSet *iface, + LONG lIndex, + ISWbemObject **objWbemObject ) +{ + FIXME( "\n" ); + return E_NOTIMPL; +} + +static const ISWbemObjectSetVtbl objectset_vtbl = +{ + objectset_QueryInterface, + objectset_AddRef, + objectset_Release, + objectset_GetTypeInfoCount, + objectset_GetTypeInfo, + objectset_GetIDsOfNames, + objectset_Invoke, + objectset_get__NewEnum, + objectset_Item, + objectset_get_Count, + objectset_get_Security_, + objectset_ItemIndex +}; + +static LONG get_object_count( IEnumWbemClassObject *iter ) +{ + LONG count = 0; + while (IEnumWbemClassObject_Skip( iter, WBEM_INFINITE, 1 ) == S_OK) count++; + IEnumWbemClassObject_Reset( iter ); + return count; +} + +static HRESULT SWbemObjectSet_create( IEnumWbemClassObject *wbem_objectenum, ISWbemObjectSet **obj ) +{ + struct objectset *objectset; + + TRACE( "%p, %p\n", obj, wbem_objectenum ); + + if (!(objectset = heap_alloc( sizeof(*objectset) ))) return E_OUTOFMEMORY; + objectset->ISWbemObjectSet_iface.lpVtbl = &objectset_vtbl; + objectset->refs = 1; + objectset->objectenum = wbem_objectenum; + IEnumWbemClassObject_AddRef( objectset->objectenum ); + objectset->count = get_object_count( objectset->objectenum ); + + *obj = &objectset->ISWbemObjectSet_iface; + TRACE( "returning iface %p\n", *obj ); + return S_OK; +} + +struct enumvar +{ + IEnumVARIANT IEnumVARIANT_iface; + LONG refs; + IEnumWbemClassObject *objectenum; +}; + +static inline struct enumvar *impl_from_IEnumVARIANT( + IEnumVARIANT *iface ) +{ + return CONTAINING_RECORD( iface, struct enumvar, IEnumVARIANT_iface ); +} + +static ULONG WINAPI enumvar_AddRef( + IEnumVARIANT *iface ) +{ + struct enumvar *enumvar = impl_from_IEnumVARIANT( iface ); + return InterlockedIncrement( &enumvar->refs ); +} + +static ULONG WINAPI enumvar_Release( + IEnumVARIANT *iface ) +{ + struct enumvar *enumvar = impl_from_IEnumVARIANT( iface ); + LONG refs = InterlockedDecrement( &enumvar->refs ); + if (!refs) + { + TRACE( "destroying %p\n", enumvar ); + IEnumWbemClassObject_Release( enumvar->objectenum ); + heap_free( enumvar ); + } + return refs; +} + +static HRESULT WINAPI enumvar_QueryInterface( + IEnumVARIANT *iface, + REFIID riid, + void **ppvObject ) +{ + struct enumvar *enumvar = impl_from_IEnumVARIANT( iface ); + + TRACE( "%p %s %p\n", enumvar, debugstr_guid(riid), ppvObject ); + + if (IsEqualGUID( riid, &IID_IEnumVARIANT ) || + IsEqualGUID( riid, &IID_IUnknown )) + { + *ppvObject = enumvar; + } + else + { + FIXME( "interface %s not implemented\n", debugstr_guid(riid) ); + return E_NOINTERFACE; + } + IEnumVARIANT_AddRef( iface ); + return S_OK; +} + +static HRESULT WINAPI enumvar_Next( IEnumVARIANT *iface, ULONG celt, VARIANT *var, ULONG *fetched ) +{ + struct enumvar *enumvar = impl_from_IEnumVARIANT( iface ); + IWbemClassObject *obj; + ULONG count = 0; + + TRACE( "%p, %u, %p, %p\n", iface, celt, var, fetched ); + + if (celt) IEnumWbemClassObject_Next( enumvar->objectenum, WBEM_INFINITE, 1, &obj, &count ); + if (count) + { + ISWbemObject *sobj; + HRESULT hr; + + hr = SWbemObject_create( obj, &sobj ); + IWbemClassObject_Release( obj ); + if (FAILED( hr )) return hr; + + V_VT( var ) = VT_DISPATCH; + V_DISPATCH( var ) = (IDispatch *)sobj; + } + if (fetched) *fetched = count; + return (count < celt) ? S_FALSE : S_OK; +} + +static HRESULT WINAPI enumvar_Skip( IEnumVARIANT *iface, ULONG celt ) +{ + struct enumvar *enumvar = impl_from_IEnumVARIANT( iface ); + + TRACE( "%p, %u\n", iface, celt ); + + return IEnumWbemClassObject_Skip( enumvar->objectenum, WBEM_INFINITE, celt ); +} + +static HRESULT WINAPI enumvar_Reset( IEnumVARIANT *iface ) +{ + struct enumvar *enumvar = impl_from_IEnumVARIANT( iface ); + + TRACE( "%p\n", iface ); + + return IEnumWbemClassObject_Reset( enumvar->objectenum ); +} + +static HRESULT WINAPI enumvar_Clone( IEnumVARIANT *iface, IEnumVARIANT **penum ) +{ + FIXME( "%p, %p\n", iface, penum ); + return E_NOTIMPL; +} + +static const struct IEnumVARIANTVtbl enumvar_vtbl = +{ + enumvar_QueryInterface, + enumvar_AddRef, + enumvar_Release, + enumvar_Next, + enumvar_Skip, + enumvar_Reset, + enumvar_Clone +}; + +static HRESULT EnumVARIANT_create( IEnumWbemClassObject *objectenum, IEnumVARIANT **obj ) +{ + struct enumvar *enumvar; + + if (!(enumvar = heap_alloc( sizeof(*enumvar) ))) return E_OUTOFMEMORY; + enumvar->IEnumVARIANT_iface.lpVtbl = &enumvar_vtbl; + enumvar->refs = 1; + enumvar->objectenum = objectenum; + IEnumWbemClassObject_AddRef( enumvar->objectenum ); + + *obj = &enumvar->IEnumVARIANT_iface; + TRACE( "returning iface %p\n", *obj ); + return S_OK; +} + +struct services +{ + ISWbemServices ISWbemServices_iface; + LONG refs; + IWbemServices *services; +}; + +static inline struct services *impl_from_ISWbemServices( + ISWbemServices *iface ) +{ + return CONTAINING_RECORD( iface, struct services, ISWbemServices_iface ); +} + +static ULONG WINAPI services_AddRef( + ISWbemServices *iface ) +{ + struct services *services = impl_from_ISWbemServices( iface ); + return InterlockedIncrement( &services->refs ); +} + +static ULONG WINAPI services_Release( + ISWbemServices *iface ) +{ + struct services *services = impl_from_ISWbemServices( iface ); + LONG refs = InterlockedDecrement( &services->refs ); + if (!refs) + { + TRACE( "destroying %p\n", services ); + IWbemServices_Release( services->services ); + heap_free( services ); + } + return refs; +} + +static HRESULT WINAPI services_QueryInterface( + ISWbemServices *iface, + REFIID riid, + void **ppvObject ) +{ + struct services *services = impl_from_ISWbemServices( iface ); + + TRACE( "%p %s %p\n", services, debugstr_guid(riid), ppvObject ); + + if (IsEqualGUID( riid, &IID_ISWbemServices ) || + IsEqualGUID( riid, &IID_IDispatch ) || + IsEqualGUID( riid, &IID_IUnknown )) + { + *ppvObject = services; + } + else + { + FIXME( "interface %s not implemented\n", debugstr_guid(riid) ); + return E_NOINTERFACE; + } + ISWbemServices_AddRef( iface ); + return S_OK; +} + +static HRESULT WINAPI services_GetTypeInfoCount( + ISWbemServices *iface, + UINT *count ) +{ + struct services *services = impl_from_ISWbemServices( iface ); + TRACE( "%p, %p\n", services, count ); + + *count = 1; + return S_OK; +} + +static HRESULT WINAPI services_GetTypeInfo( + ISWbemServices *iface, + UINT index, + LCID lcid, + ITypeInfo **info ) +{ + struct services *services = impl_from_ISWbemServices( iface ); + TRACE( "%p, %u, %u, %p\n", services, index, lcid, info ); + + return get_typeinfo( ISWbemServices_tid, info ); +} + +static HRESULT WINAPI services_GetIDsOfNames( + ISWbemServices *iface, + REFIID riid, + LPOLESTR *names, + UINT count, + LCID lcid, + DISPID *dispid ) +{ + struct services *services = impl_from_ISWbemServices( iface ); + ITypeInfo *typeinfo; + HRESULT hr; + + TRACE( "%p, %s, %p, %u, %u, %p\n", services, debugstr_guid(riid), names, count, lcid, dispid ); + + if (!names || !count || !dispid) return E_INVALIDARG; + + hr = get_typeinfo( ISWbemServices_tid, &typeinfo ); + if (SUCCEEDED(hr)) + { + hr = ITypeInfo_GetIDsOfNames( typeinfo, names, count, dispid ); + ITypeInfo_Release( typeinfo ); + } + return hr; +} + +static HRESULT WINAPI services_Invoke( + ISWbemServices *iface, + DISPID member, + REFIID riid, + LCID lcid, + WORD flags, + DISPPARAMS *params, + VARIANT *result, + EXCEPINFO *excep_info, + UINT *arg_err ) +{ + struct services *services = impl_from_ISWbemServices( iface ); + ITypeInfo *typeinfo; + HRESULT hr; + + TRACE( "%p, %d, %s, %d, %d, %p, %p, %p, %p\n", services, member, debugstr_guid(riid), + lcid, flags, params, result, excep_info, arg_err ); + + hr = get_typeinfo( ISWbemServices_tid, &typeinfo ); + if (SUCCEEDED(hr)) + { + hr = ITypeInfo_Invoke( typeinfo, &services->ISWbemServices_iface, member, flags, + params, result, excep_info, arg_err ); + ITypeInfo_Release( typeinfo ); + } + return hr; +} + +static HRESULT WINAPI services_Get( + ISWbemServices *iface, + BSTR strObjectPath, + LONG iFlags, + IDispatch *objWbemNamedValueSet, + ISWbemObject **objWbemObject ) +{ + struct services *services = impl_from_ISWbemServices( iface ); + IWbemClassObject *obj; + HRESULT hr; + + TRACE( "%p, %s, %d, %p, %p\n", iface, debugstr_w(strObjectPath), iFlags, objWbemNamedValueSet, + objWbemObject ); + + if (objWbemNamedValueSet) FIXME( "ignoring context\n" ); + + hr = IWbemServices_GetObject( services->services, strObjectPath, iFlags, NULL, &obj, NULL ); + if (hr != S_OK) return hr; + + hr = SWbemObject_create( obj, objWbemObject ); + IWbemClassObject_Release( obj ); + return hr; +} + +static HRESULT WINAPI services_GetAsync( + ISWbemServices *iface, + IDispatch *objWbemSink, + BSTR strObjectPath, + LONG iFlags, + IDispatch *objWbemNamedValueSet, + IDispatch *objWbemAsyncContext ) +{ + FIXME( "\n" ); + return E_NOTIMPL; +} + +static HRESULT WINAPI services_Delete( + ISWbemServices *iface, + BSTR strObjectPath, + LONG iFlags, + IDispatch *objWbemNamedValueSet ) +{ + FIXME( "\n" ); + return E_NOTIMPL; +} + +static HRESULT WINAPI services_DeleteAsync( + ISWbemServices* This, + IDispatch *objWbemSink, + BSTR strObjectPath, + LONG iFlags, + IDispatch *objWbemNamedValueSet, + IDispatch *objWbemAsyncContext ) +{ + FIXME( "\n" ); + return E_NOTIMPL; +} + +static BSTR build_query_string( const WCHAR *class ) +{ + static const WCHAR selectW[] = {'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ',0}; + UINT len = strlenW(class) + sizeof(selectW) / sizeof(selectW[0]); + BSTR ret; + + if (!(ret = SysAllocStringLen( NULL, len ))) return NULL; + strcpyW( ret, selectW ); + strcatW( ret, class ); + return ret; +} + +static HRESULT WINAPI services_InstancesOf( + ISWbemServices *iface, + BSTR strClass, + LONG iFlags, + IDispatch *objWbemNamedValueSet, + ISWbemObjectSet **objWbemObjectSet ) +{ + static const WCHAR wqlW[] = {'W','Q','L',0}; + BSTR query, wql = SysAllocString( wqlW ); + HRESULT hr; + + TRACE( "%p, %s, %x, %p, %p\n", iface, debugstr_w(strClass), iFlags, objWbemNamedValueSet, + objWbemObjectSet ); + + if (!(query = build_query_string( strClass ))) + { + SysFreeString( wql ); + return E_OUTOFMEMORY; + } + hr = ISWbemServices_ExecQuery( iface, query, wql, iFlags, objWbemNamedValueSet, objWbemObjectSet ); + SysFreeString( wql ); + SysFreeString( query ); + return hr; +} + +static HRESULT WINAPI services_InstancesOfAsync( + ISWbemServices *iface, + IDispatch *objWbemSink, + BSTR strClass, + LONG iFlags, + IDispatch *objWbemNamedValueSet, + IDispatch *objWbemAsyncContext ) +{ + FIXME( "\n" ); + return E_NOTIMPL; +} + +static HRESULT WINAPI services_SubclassesOf( + ISWbemServices *iface, + BSTR strSuperclass, + LONG iFlags, + IDispatch *objWbemNamedValueSet, + ISWbemObjectSet **objWbemObjectSet ) +{ + FIXME( "\n" ); + return E_NOTIMPL; +} + +static HRESULT WINAPI services_SubclassesOfAsync( + ISWbemServices *iface, + IDispatch *objWbemSink, + BSTR strSuperclass, + LONG iFlags, + IDispatch *objWbemNamedValueSet, + IDispatch *objWbemAsyncContext ) +{ + FIXME( "\n" ); + return E_NOTIMPL; +} + +static HRESULT WINAPI services_ExecQuery( + ISWbemServices *iface, + BSTR strQuery, + BSTR strQueryLanguage, + LONG iFlags, + IDispatch *objWbemNamedValueSet, + ISWbemObjectSet **objWbemObjectSet ) +{ + struct services *services = impl_from_ISWbemServices( iface ); + IEnumWbemClassObject *iter; + HRESULT hr; + + TRACE( "%p, %s, %s, %x, %p, %p\n", iface, debugstr_w(strQuery), debugstr_w(strQueryLanguage), + iFlags, objWbemNamedValueSet, objWbemObjectSet ); + + if (objWbemNamedValueSet) FIXME( "ignoring context\n" ); + + hr = IWbemServices_ExecQuery( services->services, strQueryLanguage, strQuery, iFlags, NULL, &iter ); + if (hr != S_OK) return hr; + + hr = SWbemObjectSet_create( iter, objWbemObjectSet ); + IEnumWbemClassObject_Release( iter ); + return hr; +} + +static HRESULT WINAPI services_ExecQueryAsync( + ISWbemServices *iface, + IDispatch *objWbemSink, + BSTR strQuery, + BSTR strQueryLanguage, + LONG lFlags, + IDispatch *objWbemNamedValueSet, + IDispatch *objWbemAsyncContext ) +{ + FIXME( "\n" ); + return E_NOTIMPL; +} + +static HRESULT WINAPI services_AssociatorsOf( + ISWbemServices *iface, + BSTR strObjectPath, + BSTR strAssocClass, + BSTR strResultClass, + BSTR strResultRole, + BSTR strRole, + VARIANT_BOOL bClassesOnly, + VARIANT_BOOL bSchemaOnly, + BSTR strRequiredAssocQualifier, + BSTR strRequiredQualifier, + LONG iFlags, + IDispatch *objWbemNamedValueSet, + ISWbemObjectSet **objWbemObjectSet ) +{ + FIXME( "\n" ); + return E_NOTIMPL; +} + +static HRESULT WINAPI services_AssociatorsOfAsync( + ISWbemServices *iface, + IDispatch *objWbemSink, + BSTR strObjectPath, + BSTR strAssocClass, + BSTR strResultClass, + BSTR strResultRole, + BSTR strRole, + VARIANT_BOOL bClassesOnly, + VARIANT_BOOL bSchemaOnly, + BSTR strRequiredAssocQualifier, + BSTR strRequiredQualifier, + LONG iFlags, + IDispatch *objWbemNamedValueSet, + IDispatch *objWbemAsyncContext ) +{ + FIXME( "\n" ); + return E_NOTIMPL; +} + +static HRESULT WINAPI services_ReferencesTo( + ISWbemServices *iface, + BSTR strObjectPath, + BSTR strResultClass, + BSTR strRole, + VARIANT_BOOL bClassesOnly, + VARIANT_BOOL bSchemaOnly, + BSTR strRequiredQualifier, + LONG iFlags, + IDispatch *objWbemNamedValueSet, + ISWbemObjectSet **objWbemObjectSet ) +{ + FIXME( "\n" ); + return E_NOTIMPL; +} + +static HRESULT WINAPI services_ReferencesToAsync( + ISWbemServices *iface, + IDispatch *objWbemSink, + BSTR strObjectPath, + BSTR strResultClass, + BSTR strRole, + VARIANT_BOOL bClassesOnly, + VARIANT_BOOL bSchemaOnly, + BSTR strRequiredQualifier, + LONG iFlags, + IDispatch *objWbemNamedValueSet, + IDispatch *objWbemAsyncContext ) +{ + FIXME( "\n" ); + return E_NOTIMPL; +} + +static HRESULT WINAPI services_ExecNotificationQuery( + ISWbemServices *iface, + BSTR strQuery, + BSTR strQueryLanguage, + LONG iFlags, + IDispatch *objWbemNamedValueSet, + ISWbemEventSource **objWbemEventSource ) +{ + FIXME( "\n" ); + return E_NOTIMPL; +} + +static HRESULT WINAPI services_ExecNotificationQueryAsync( + ISWbemServices *iface, + IDispatch *objWbemSink, + BSTR strQuery, + BSTR strQueryLanguage, + LONG iFlags, + IDispatch *objWbemNamedValueSet, + IDispatch *objWbemAsyncContext ) +{ + FIXME( "\n" ); + return E_NOTIMPL; +} + +static HRESULT WINAPI services_ExecMethod( + ISWbemServices *iface, + BSTR strObjectPath, + BSTR strMethodName, + IDispatch *objWbemInParameters, + LONG iFlags, + IDispatch *objWbemNamedValueSet, + ISWbemObject **objWbemOutParameters ) +{ + FIXME( "\n" ); + return E_NOTIMPL; +} + +static HRESULT WINAPI services_ExecMethodAsync( + ISWbemServices *iface, + IDispatch *objWbemSink, + BSTR strObjectPath, + BSTR strMethodName, + IDispatch *objWbemInParameters, + LONG iFlags, + IDispatch *objWbemNamedValueSet, + IDispatch *objWbemAsyncContext ) +{ + FIXME( "\n" ); + return E_NOTIMPL; +} + +static HRESULT WINAPI services_get_Security_( + ISWbemServices *iface, + ISWbemSecurity **objWbemSecurity ) +{ + TRACE( "%p, %p\n", iface, objWbemSecurity ); + + if (!objWbemSecurity) + return E_INVALIDARG; + + return ISWbemSecurity_create( objWbemSecurity ); +} + +static const ISWbemServicesVtbl services_vtbl = +{ + services_QueryInterface, + services_AddRef, + services_Release, + services_GetTypeInfoCount, + services_GetTypeInfo, + services_GetIDsOfNames, + services_Invoke, + services_Get, + services_GetAsync, + services_Delete, + services_DeleteAsync, + services_InstancesOf, + services_InstancesOfAsync, + services_SubclassesOf, + services_SubclassesOfAsync, + services_ExecQuery, + services_ExecQueryAsync, + services_AssociatorsOf, + services_AssociatorsOfAsync, + services_ReferencesTo, + services_ReferencesToAsync, + services_ExecNotificationQuery, + services_ExecNotificationQueryAsync, + services_ExecMethod, + services_ExecMethodAsync, + services_get_Security_ +}; + +static HRESULT SWbemServices_create( IWbemServices *wbem_services, ISWbemServices **obj ) +{ + struct services *services; + + TRACE( "%p, %p\n", obj, wbem_services ); + + if (!(services = heap_alloc( sizeof(*services) ))) return E_OUTOFMEMORY; + services->ISWbemServices_iface.lpVtbl = &services_vtbl; + services->refs = 1; + services->services = wbem_services; + IWbemServices_AddRef( services->services ); + + *obj = &services->ISWbemServices_iface; + TRACE( "returning iface %p\n", *obj ); + return S_OK; +} + +struct locator +{ + ISWbemLocator ISWbemLocator_iface; + LONG refs; + IWbemLocator *locator; +}; + +static inline struct locator *impl_from_ISWbemLocator( ISWbemLocator *iface ) +{ + return CONTAINING_RECORD( iface, struct locator, ISWbemLocator_iface ); +} + +static ULONG WINAPI locator_AddRef( + ISWbemLocator *iface ) +{ + struct locator *locator = impl_from_ISWbemLocator( iface ); + return InterlockedIncrement( &locator->refs ); +} + +static ULONG WINAPI locator_Release( + ISWbemLocator *iface ) +{ + struct locator *locator = impl_from_ISWbemLocator( iface ); + LONG refs = InterlockedDecrement( &locator->refs ); + if (!refs) + { + TRACE( "destroying %p\n", locator ); + if (locator->locator) + IWbemLocator_Release( locator->locator ); + heap_free( locator ); + } + return refs; +} + +static HRESULT WINAPI locator_QueryInterface( + ISWbemLocator *iface, + REFIID riid, + void **ppvObject ) +{ + struct locator *locator = impl_from_ISWbemLocator( iface ); + + TRACE( "%p, %s, %p\n", locator, debugstr_guid( riid ), ppvObject ); + + if (IsEqualGUID( riid, &IID_ISWbemLocator ) || + IsEqualGUID( riid, &IID_IDispatch ) || + IsEqualGUID( riid, &IID_IUnknown )) + { + *ppvObject = iface; + } + else + { + FIXME( "interface %s not implemented\n", debugstr_guid(riid) ); + return E_NOINTERFACE; + } + ISWbemLocator_AddRef( iface ); + return S_OK; +} + +static HRESULT WINAPI locator_GetTypeInfoCount( + ISWbemLocator *iface, + UINT *count ) +{ + struct locator *locator = impl_from_ISWbemLocator( iface ); + + TRACE( "%p, %p\n", locator, count ); + *count = 1; + return S_OK; +} + +static HRESULT WINAPI locator_GetTypeInfo( + ISWbemLocator *iface, + UINT index, + LCID lcid, + ITypeInfo **info ) +{ + struct locator *locator = impl_from_ISWbemLocator( iface ); + TRACE( "%p, %u, %u, %p\n", locator, index, lcid, info ); + + return get_typeinfo( ISWbemLocator_tid, info ); +} + +static HRESULT WINAPI locator_GetIDsOfNames( + ISWbemLocator *iface, + REFIID riid, + LPOLESTR *names, + UINT count, + LCID lcid, + DISPID *dispid ) +{ + struct locator *locator = impl_from_ISWbemLocator( iface ); + ITypeInfo *typeinfo; + HRESULT hr; + + TRACE( "%p, %s, %p, %u, %u, %p\n", locator, debugstr_guid(riid), names, count, lcid, dispid ); + + if (!names || !count || !dispid) return E_INVALIDARG; + + hr = get_typeinfo( ISWbemLocator_tid, &typeinfo ); + if (SUCCEEDED(hr)) + { + hr = ITypeInfo_GetIDsOfNames( typeinfo, names, count, dispid ); + ITypeInfo_Release( typeinfo ); + } + return hr; +} + +static HRESULT WINAPI locator_Invoke( + ISWbemLocator *iface, + DISPID member, + REFIID riid, + LCID lcid, + WORD flags, + DISPPARAMS *params, + VARIANT *result, + EXCEPINFO *excep_info, + UINT *arg_err ) +{ + struct locator *locator = impl_from_ISWbemLocator( iface ); + ITypeInfo *typeinfo; + HRESULT hr; + + TRACE( "%p, %d, %s, %d, %d, %p, %p, %p, %p\n", locator, member, debugstr_guid(riid), + lcid, flags, params, result, excep_info, arg_err ); + + hr = get_typeinfo( ISWbemLocator_tid, &typeinfo ); + if (SUCCEEDED(hr)) + { + hr = ITypeInfo_Invoke( typeinfo, &locator->ISWbemLocator_iface, member, flags, + params, result, excep_info, arg_err ); + ITypeInfo_Release( typeinfo ); + } + return hr; +} + +static BSTR build_resource_string( BSTR server, BSTR namespace ) +{ + static const WCHAR defaultW[] = {'r','o','o','t','\\','d','e','f','a','u','l','t',0}; + ULONG len, len_server = 0, len_namespace = 0; + BSTR ret; + + if (server && *server) len_server = strlenW( server ); + else len_server = 1; + if (namespace && *namespace) len_namespace = strlenW( namespace ); + else len_namespace = sizeof(defaultW) / sizeof(defaultW[0]) - 1; + + if (!(ret = SysAllocStringLen( NULL, 2 + len_server + 1 + len_namespace ))) return NULL; + + ret[0] = ret[1] = '\\'; + if (server && *server) strcpyW( ret + 2, server ); + else ret[2] = '.'; + + len = len_server + 2; + ret[len++] = '\\'; + + if (namespace && *namespace) strcpyW( ret + len, namespace ); + else strcpyW( ret + len, defaultW ); + return ret; +} + +static HRESULT WINAPI locator_ConnectServer( + ISWbemLocator *iface, + BSTR strServer, + BSTR strNamespace, + BSTR strUser, + BSTR strPassword, + BSTR strLocale, + BSTR strAuthority, + LONG iSecurityFlags, + IDispatch *objWbemNamedValueSet, + ISWbemServices **objWbemServices ) +{ + struct locator *locator = impl_from_ISWbemLocator( iface ); + IWbemServices *services; + BSTR resource; + HRESULT hr; + + TRACE( "%p, %s, %s, %s, %p, %s, %s, 0x%08x, %p, %p\n", iface, debugstr_w(strServer), + debugstr_w(strNamespace), debugstr_w(strUser), strPassword, debugstr_w(strLocale), + debugstr_w(strAuthority), iSecurityFlags, objWbemNamedValueSet, objWbemServices ); + + if (objWbemNamedValueSet) FIXME( "context not supported\n" ); + + if (!locator->locator) + { + hr = CoCreateInstance( &CLSID_WbemLocator, NULL, CLSCTX_INPROC_SERVER, &IID_IWbemLocator, + (void **)&locator->locator ); + if (hr != S_OK) return hr; + } + + if (!(resource = build_resource_string( strServer, strNamespace ))) return E_OUTOFMEMORY; + hr = IWbemLocator_ConnectServer( locator->locator, resource, strUser, strPassword, strLocale, + iSecurityFlags, strAuthority, NULL, &services ); + SysFreeString( resource ); + if (hr != S_OK) return hr; + + hr = SWbemServices_create( services, objWbemServices ); + IWbemServices_Release( services ); + return hr; +} + +static HRESULT WINAPI locator_get_Security_( + ISWbemLocator *iface, + ISWbemSecurity **objWbemSecurity ) +{ + TRACE( "%p, %p\n", iface, objWbemSecurity ); + + if (!objWbemSecurity) + return E_INVALIDARG; + + return ISWbemSecurity_create( objWbemSecurity ); +} + +static const ISWbemLocatorVtbl locator_vtbl = +{ + locator_QueryInterface, + locator_AddRef, + locator_Release, + locator_GetTypeInfoCount, + locator_GetTypeInfo, + locator_GetIDsOfNames, + locator_Invoke, + locator_ConnectServer, + locator_get_Security_ +}; + +HRESULT SWbemLocator_create( void **obj ) +{ + struct locator *locator; + + TRACE( "%p\n", obj ); + + if (!(locator = heap_alloc( sizeof(*locator) ))) return E_OUTOFMEMORY; + locator->ISWbemLocator_iface.lpVtbl = &locator_vtbl; + locator->refs = 1; + locator->locator = NULL; + + *obj = &locator->ISWbemLocator_iface; + TRACE( "returning iface %p\n", *obj ); + return S_OK; +} + +struct security +{ + ISWbemSecurity ISWbemSecurity_iface; + LONG refs; + WbemImpersonationLevelEnum implevel; + WbemAuthenticationLevelEnum authlevel; +}; + +static inline struct security *impl_from_ISWbemSecurity( ISWbemSecurity *iface ) +{ + return CONTAINING_RECORD( iface, struct security, ISWbemSecurity_iface ); +} + +static ULONG WINAPI security_AddRef( + ISWbemSecurity *iface ) +{ + struct security *security = impl_from_ISWbemSecurity( iface ); + return InterlockedIncrement( &security->refs ); +} + +static ULONG WINAPI security_Release( + ISWbemSecurity *iface ) +{ + struct security *security = impl_from_ISWbemSecurity( iface ); + LONG refs = InterlockedDecrement( &security->refs ); + if (!refs) + { + TRACE( "destroying %p\n", security ); + heap_free( security ); + } + return refs; +} + +static HRESULT WINAPI security_QueryInterface( + ISWbemSecurity *iface, + REFIID riid, + void **ppvObject ) +{ + struct security *security = impl_from_ISWbemSecurity( iface ); + TRACE( "%p, %s, %p\n", security, debugstr_guid( riid ), ppvObject ); + + if (IsEqualGUID( riid, &IID_ISWbemSecurity ) || + IsEqualGUID( riid, &IID_IDispatch ) || + IsEqualGUID( riid, &IID_IUnknown )) + { + *ppvObject = iface; + } + else + { + FIXME( "interface %s not implemented\n", debugstr_guid(riid) ); + return E_NOINTERFACE; + } + ISWbemSecurity_AddRef( iface ); + return S_OK; +} + +static HRESULT WINAPI security_GetTypeInfoCount( + ISWbemSecurity *iface, + UINT *count ) +{ + struct security *security = impl_from_ISWbemSecurity( iface ); + TRACE( "%p, %p\n", security, count ); + + *count = 1; + return S_OK; +} + +static HRESULT WINAPI security_GetTypeInfo( + ISWbemSecurity *iface, + UINT index, + LCID lcid, + ITypeInfo **info ) +{ + struct security *security = impl_from_ISWbemSecurity( iface ); + TRACE( "%p, %u, %u, %p\n", security, index, lcid, info ); + + return get_typeinfo( ISWbemSecurity_tid, info ); +} + +static HRESULT WINAPI security_GetIDsOfNames( + ISWbemSecurity *iface, + REFIID riid, + LPOLESTR *names, + UINT count, + LCID lcid, + DISPID *dispid ) +{ + struct security *security = impl_from_ISWbemSecurity( iface ); + ITypeInfo *typeinfo; + HRESULT hr; + + TRACE( "%p, %s, %p, %u, %u, %p\n", security, debugstr_guid(riid), names, count, lcid, dispid ); + + if (!names || !count || !dispid) return E_INVALIDARG; + + hr = get_typeinfo( ISWbemSecurity_tid, &typeinfo ); + if (SUCCEEDED(hr)) + { + hr = ITypeInfo_GetIDsOfNames( typeinfo, names, count, dispid ); + ITypeInfo_Release( typeinfo ); + } + return hr; +} + +static HRESULT WINAPI security_Invoke( + ISWbemSecurity *iface, + DISPID member, + REFIID riid, + LCID lcid, + WORD flags, + DISPPARAMS *params, + VARIANT *result, + EXCEPINFO *excep_info, + UINT *arg_err ) +{ + struct security *security = impl_from_ISWbemSecurity( iface ); + ITypeInfo *typeinfo; + HRESULT hr; + + TRACE( "%p, %d, %s, %d, %d, %p, %p, %p, %p\n", security, member, debugstr_guid(riid), + lcid, flags, params, result, excep_info, arg_err ); + + hr = get_typeinfo( ISWbemSecurity_tid, &typeinfo ); + if (SUCCEEDED(hr)) + { + hr = ITypeInfo_Invoke( typeinfo, &security->ISWbemSecurity_iface, member, flags, + params, result, excep_info, arg_err ); + ITypeInfo_Release( typeinfo ); + } + return hr; +} + +static HRESULT WINAPI security_get_ImpersonationLevel_( + ISWbemSecurity *iface, + WbemImpersonationLevelEnum *impersonation_level ) +{ + struct security *security = impl_from_ISWbemSecurity( iface ); + FIXME( "%p, %p: stub\n", security, impersonation_level ); + + if (!impersonation_level) + return E_INVALIDARG; + + *impersonation_level = security->implevel; + return S_OK; +} + +static HRESULT WINAPI security_put_ImpersonationLevel_( + ISWbemSecurity *iface, + WbemImpersonationLevelEnum impersonation_level ) +{ + struct security *security = impl_from_ISWbemSecurity( iface ); + FIXME( "%p, %d: stub\n", security, impersonation_level ); + + security->implevel = impersonation_level; + return S_OK; +} + +static HRESULT WINAPI security_get_AuthenticationLevel_( + ISWbemSecurity *iface, + WbemAuthenticationLevelEnum *authentication_level ) +{ + struct security *security = impl_from_ISWbemSecurity( iface ); + FIXME( "%p, %p: stub\n", security, authentication_level ); + + if (!authentication_level) + return E_INVALIDARG; + + *authentication_level = security->authlevel; + return S_OK; +} + +static HRESULT WINAPI security_put_AuthenticationLevel_( + ISWbemSecurity *iface, + WbemAuthenticationLevelEnum authentication_level ) +{ + struct security *security = impl_from_ISWbemSecurity( iface ); + FIXME( "%p, %d: stub\n", security, authentication_level ); + + security->authlevel = authentication_level; + return S_OK; +} + +static HRESULT WINAPI security_get_Privileges_( + ISWbemSecurity *iface, + ISWbemPrivilegeSet **privilege_set ) +{ + struct security *security = impl_from_ISWbemSecurity( iface ); + FIXME( "%p, %p: stub\n", security, privilege_set ); + + if (!privilege_set) + return E_INVALIDARG; + + return E_NOTIMPL; +} + +static const ISWbemSecurityVtbl security_vtbl = +{ + security_QueryInterface, + security_AddRef, + security_Release, + security_GetTypeInfoCount, + security_GetTypeInfo, + security_GetIDsOfNames, + security_Invoke, + security_get_ImpersonationLevel_, + security_put_ImpersonationLevel_, + security_get_AuthenticationLevel_, + security_put_AuthenticationLevel_, + security_get_Privileges_ +}; + +static HRESULT ISWbemSecurity_create( ISWbemSecurity **obj ) +{ + struct security *security; + + TRACE( "%p\n", obj ); + + if (!(security = heap_alloc( sizeof(*security) ))) return E_OUTOFMEMORY; + security->ISWbemSecurity_iface.lpVtbl = &security_vtbl; + security->refs = 1; + security->implevel = wbemImpersonationLevelAnonymous; + security->authlevel = wbemAuthenticationLevelDefault; + + *obj = &security->ISWbemSecurity_iface; + TRACE( "returning iface %p\n", *obj ); + return S_OK; +} diff --git a/reactos/dll/win32/wbemdisp/main.c b/reactos/dll/win32/wbemdisp/main.c new file mode 100644 index 00000000000..e6a3dc28b0a --- /dev/null +++ b/reactos/dll/win32/wbemdisp/main.c @@ -0,0 +1,551 @@ +/* + * Copyright 2013 Hans Leidekker for CodeWeavers + * + * 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 "wbemdisp_private.h" + +#include +#include +#include + +static HINSTANCE instance; + +struct moniker +{ + IMoniker IMoniker_iface; + LONG refs; + IUnknown *obj; +}; + +static inline struct moniker *impl_from_IMoniker( + IMoniker *iface ) +{ + return CONTAINING_RECORD( iface, struct moniker, IMoniker_iface ); +} + +static ULONG WINAPI moniker_AddRef( + IMoniker *iface ) +{ + struct moniker *moniker = impl_from_IMoniker( iface ); + return InterlockedIncrement( &moniker->refs ); +} + +static ULONG WINAPI moniker_Release( + IMoniker *iface ) +{ + struct moniker *moniker = impl_from_IMoniker( iface ); + LONG refs = InterlockedDecrement( &moniker->refs ); + if (!refs) + { + TRACE( "destroying %p\n", moniker ); + IUnknown_Release( moniker->obj ); + heap_free( moniker ); + } + return refs; +} + +static HRESULT WINAPI moniker_QueryInterface( + IMoniker *iface, REFIID riid, void **ppvObject ) +{ + struct moniker *moniker = impl_from_IMoniker( iface ); + + TRACE( "%p, %s, %p\n", moniker, debugstr_guid( riid ), ppvObject ); + + if (IsEqualGUID( riid, &IID_IMoniker ) || + IsEqualGUID( riid, &IID_IUnknown )) + { + *ppvObject = iface; + } + else + { + FIXME( "interface %s not implemented\n", debugstr_guid(riid) ); + return E_NOINTERFACE; + } + IMoniker_AddRef( iface ); + return S_OK; +} + +static HRESULT WINAPI moniker_GetClassID( + IMoniker *iface, CLSID *pClassID ) +{ + FIXME( "\n" ); + return E_NOTIMPL; +} + +static HRESULT WINAPI moniker_IsDirty( + IMoniker *iface ) +{ + FIXME( "\n" ); + return E_NOTIMPL; +} + +static HRESULT WINAPI moniker_Load( + IMoniker *iface, IStream *pStm ) +{ + FIXME( "\n" ); + return E_NOTIMPL; +} + +static HRESULT WINAPI moniker_Save( + IMoniker *iface, IStream *pStm, BOOL fClearDirty ) +{ + FIXME( "\n" ); + return E_NOTIMPL; +} + +static HRESULT WINAPI moniker_GetSizeMax( + IMoniker *iface, ULARGE_INTEGER *pcbSize ) +{ + FIXME( "\n" ); + return E_NOTIMPL; +} + +static HRESULT WINAPI moniker_BindToObject( + IMoniker *iface, IBindCtx *pbc, IMoniker *pmkToLeft, REFIID riidResult, void **ppvResult ) +{ + struct moniker *moniker = impl_from_IMoniker( iface ); + + TRACE( "%p, %p, %p, %s, %p\n", iface, pbc, pmkToLeft, debugstr_guid(riidResult), ppvResult ); + return IUnknown_QueryInterface( moniker->obj, riidResult, ppvResult ); +} + +static HRESULT WINAPI moniker_BindToStorage( + IMoniker *iface, IBindCtx *pbc, IMoniker *pmkToLeft, REFIID riid, void **ppvObj ) +{ + FIXME( "\n" ); + return E_NOTIMPL; +} + +static HRESULT WINAPI moniker_Reduce( + IMoniker *iface, IBindCtx *pbc, DWORD dwReduceHowFar, IMoniker **ppmkToLeft, IMoniker **ppmkReduced ) +{ + FIXME( "\n" ); + return E_NOTIMPL; +} + +static HRESULT WINAPI moniker_ComposeWith( + IMoniker *iface, IMoniker *pmkRight, BOOL fOnlyIfNotGeneric, IMoniker **ppmkComposite ) +{ + FIXME( "\n" ); + return E_NOTIMPL; +} + +static HRESULT WINAPI moniker_Enum( + IMoniker *iface, BOOL fForward, IEnumMoniker **ppenumMoniker ) +{ + FIXME( "\n" ); + return E_NOTIMPL; +} + +static HRESULT WINAPI moniker_IsEqual( + IMoniker *iface, IMoniker *pmkOtherMoniker ) +{ + FIXME( "\n" ); + return E_NOTIMPL; +} + +static HRESULT WINAPI moniker_Hash( + IMoniker *iface, DWORD *pdwHash ) +{ + FIXME( "\n" ); + return E_NOTIMPL; +} + +static HRESULT WINAPI moniker_IsRunning( + IMoniker *iface, IBindCtx *pbc, IMoniker *pmkToLeft, IMoniker *pmkNewlyRunning ) +{ + FIXME( "\n" ); + return E_NOTIMPL; +} + +static HRESULT WINAPI moniker_GetTimeOfLastChange( + IMoniker *iface, IBindCtx *pbc, IMoniker *pmkToLeft, FILETIME *pFileTime ) +{ + FIXME( "\n" ); + return E_NOTIMPL; +} + +static HRESULT WINAPI moniker_Inverse( + IMoniker *iface, IMoniker **ppmk ) +{ + FIXME( "\n" ); + return E_NOTIMPL; +} + +static HRESULT WINAPI moniker_CommonPrefixWith( + IMoniker *iface, IMoniker *pmkOther, IMoniker **ppmkPrefix ) +{ + FIXME( "\n" ); + return E_NOTIMPL; +} + +static HRESULT WINAPI moniker_RelativePathTo( + IMoniker *iface, IMoniker *pmkOther, IMoniker **ppmkRelPath ) +{ + FIXME( "\n" ); + return E_NOTIMPL; +} + +static HRESULT WINAPI moniker_GetDisplayName( + IMoniker *iface, IBindCtx *pbc, IMoniker *pmkToLeft, LPOLESTR *ppszDisplayName ) +{ + FIXME( "\n" ); + return E_NOTIMPL; +} + +static HRESULT WINAPI moniker_ParseDisplayName( + IMoniker *iface, IBindCtx *pbc, IMoniker *pmkToLeft, LPOLESTR pszDisplayName, ULONG *pchEaten, + IMoniker **ppmkOut ) +{ + FIXME( "\n" ); + return E_NOTIMPL; +} + +static HRESULT WINAPI moniker_IsSystemMoniker( + IMoniker *iface, DWORD *pdwMksys ) +{ + FIXME( "\n" ); + return E_NOTIMPL; +} + +static const IMonikerVtbl moniker_vtbl = +{ + moniker_QueryInterface, + moniker_AddRef, + moniker_Release, + moniker_GetClassID, + moniker_IsDirty, + moniker_Load, + moniker_Save, + moniker_GetSizeMax, + moniker_BindToObject, + moniker_BindToStorage, + moniker_Reduce, + moniker_ComposeWith, + moniker_Enum, + moniker_IsEqual, + moniker_Hash, + moniker_IsRunning, + moniker_GetTimeOfLastChange, + moniker_Inverse, + moniker_CommonPrefixWith, + moniker_RelativePathTo, + moniker_GetDisplayName, + moniker_ParseDisplayName, + moniker_IsSystemMoniker +}; + +static HRESULT Moniker_create( IUnknown *unk, IMoniker **obj ) +{ + struct moniker *moniker; + + TRACE( "%p, %p\n", unk, obj ); + + if (!(moniker = heap_alloc( sizeof(*moniker) ))) return E_OUTOFMEMORY; + moniker->IMoniker_iface.lpVtbl = &moniker_vtbl; + moniker->refs = 1; + moniker->obj = unk; + IUnknown_AddRef( moniker->obj ); + + *obj = &moniker->IMoniker_iface; + TRACE( "returning iface %p\n", *obj ); + return S_OK; +} + +static HRESULT WINAPI WinMGMTS_QueryInterface(IParseDisplayName *iface, REFIID riid, void **ppv) +{ + if(IsEqualGUID(riid, &IID_IUnknown)) { + TRACE("(IID_IUnknown %p)\n", ppv); + *ppv = iface; + }else if(IsEqualGUID(riid, &IID_IParseDisplayName)) { + TRACE("(IID_IParseDisplayName %p)\n", ppv); + *ppv = iface; + }else { + WARN("Unsupported riid %s\n", debugstr_guid(riid)); + *ppv = NULL; + return E_NOINTERFACE; + } + + IUnknown_AddRef((IUnknown*)*ppv); + return S_OK; +} + +static ULONG WINAPI WinMGMTS_AddRef(IParseDisplayName *iface) +{ + return 2; +} + +static ULONG WINAPI WinMGMTS_Release(IParseDisplayName *iface) +{ + return 1; +} + +static HRESULT parse_path( const WCHAR *str, BSTR *server, BSTR *namespace, BSTR *relative ) +{ + IWbemPath *path; + ULONG len; + HRESULT hr; + + *server = *namespace = *relative = NULL; + + hr = CoCreateInstance( &CLSID_WbemDefPath, NULL, CLSCTX_INPROC_SERVER, &IID_IWbemPath, (void **)&path ); + if (hr != S_OK) return hr; + + hr = IWbemPath_SetText( path, WBEMPATH_CREATE_ACCEPT_ALL, str ); + if (hr != S_OK) goto done; + + len = 0; + hr = IWbemPath_GetServer( path, &len, NULL ); + if (hr == S_OK) + { + if (!(*server = SysAllocStringLen( NULL, len ))) + { + hr = E_OUTOFMEMORY; + goto done; + } + hr = IWbemPath_GetServer( path, &len, *server ); + if (hr != S_OK) goto done; + } + + len = 0; + hr = IWbemPath_GetText( path, WBEMPATH_GET_NAMESPACE_ONLY, &len, NULL ); + if (hr == S_OK) + { + if (!(*namespace = SysAllocStringLen( NULL, len ))) + { + hr = E_OUTOFMEMORY; + goto done; + } + hr = IWbemPath_GetText( path, WBEMPATH_GET_NAMESPACE_ONLY, &len, *namespace ); + if (hr != S_OK) goto done; + } + len = 0; + hr = IWbemPath_GetText( path, WBEMPATH_GET_RELATIVE_ONLY, &len, NULL ); + if (hr == S_OK) + { + if (!(*relative = SysAllocStringLen( NULL, len ))) + { + hr = E_OUTOFMEMORY; + goto done; + } + hr = IWbemPath_GetText( path, WBEMPATH_GET_RELATIVE_ONLY, &len, *relative ); + } + +done: + IWbemPath_Release( path ); + if (hr != S_OK) + { + SysFreeString( *server ); + SysFreeString( *namespace ); + SysFreeString( *relative ); + } + return hr; +} + +static HRESULT WINAPI WinMGMTS_ParseDisplayName(IParseDisplayName *iface, IBindCtx *pbc, LPOLESTR pszDisplayName, + ULONG *pchEaten, IMoniker **ppmkOut) +{ + static const WCHAR prefixW[] = {'w','i','n','m','g','m','t','s',':',0}; + const DWORD prefix_len = sizeof(prefixW) / sizeof(prefixW[0]) - 1; + ISWbemLocator *locator = NULL; + ISWbemServices *services = NULL; + ISWbemObject *obj = NULL; + BSTR server, namespace, relative; + WCHAR *p; + HRESULT hr; + + TRACE( "%p, %p, %s, %p, %p\n", iface, pbc, debugstr_w(pszDisplayName), pchEaten, ppmkOut ); + + if (strncmpiW( pszDisplayName, prefixW, prefix_len )) return MK_E_SYNTAX; + + p = pszDisplayName + prefix_len; + if (*p == '{') + { + FIXME( "ignoring security settings\n" ); + while (*p && *p != '}') p++; + if (*p == '}') p++; + if (*p == '!') p++; + } + hr = parse_path( p, &server, &namespace, &relative ); + if (hr != S_OK) return hr; + + hr = SWbemLocator_create( (void **)&locator ); + if (hr != S_OK) goto done; + + hr = ISWbemLocator_ConnectServer( locator, server, namespace, NULL, NULL, NULL, NULL, 0, NULL, &services ); + if (hr != S_OK) goto done; + + if (!relative || !*relative) Moniker_create( (IUnknown *)services, ppmkOut ); + else + { + hr = ISWbemServices_Get( services, relative, 0, NULL, &obj ); + if (hr != S_OK) goto done; + hr = Moniker_create( (IUnknown *)obj, ppmkOut ); + } + +done: + if (obj) ISWbemObject_Release( obj ); + if (services) ISWbemServices_Release( services ); + if (locator) ISWbemLocator_Release( locator ); + SysFreeString( server ); + SysFreeString( namespace ); + SysFreeString( relative ); + if (hr == S_OK) *pchEaten = strlenW( pszDisplayName ); + return hr; +} + +static const IParseDisplayNameVtbl WinMGMTSVtbl = { + WinMGMTS_QueryInterface, + WinMGMTS_AddRef, + WinMGMTS_Release, + WinMGMTS_ParseDisplayName +}; + +static IParseDisplayName winmgmts = { &WinMGMTSVtbl }; + +static HRESULT WinMGMTS_create(void **ppv) +{ + *ppv = &winmgmts; + return S_OK; +} + +struct factory +{ + IClassFactory IClassFactory_iface; + HRESULT (*fnCreateInstance)( LPVOID * ); +}; + +static inline struct factory *impl_from_IClassFactory( IClassFactory *iface ) +{ + return CONTAINING_RECORD( iface, struct factory, IClassFactory_iface ); +} + +static HRESULT WINAPI factory_QueryInterface( IClassFactory *iface, REFIID riid, LPVOID *obj ) +{ + if (IsEqualGUID( riid, &IID_IUnknown ) || IsEqualGUID( riid, &IID_IClassFactory )) + { + IClassFactory_AddRef( iface ); + *obj = iface; + return S_OK; + } + FIXME( "interface %s not implemented\n", debugstr_guid(riid) ); + return E_NOINTERFACE; +} + +static ULONG WINAPI factory_AddRef( IClassFactory *iface ) +{ + return 2; +} + +static ULONG WINAPI factory_Release( IClassFactory *iface ) +{ + return 1; +} + +static HRESULT WINAPI factory_CreateInstance( IClassFactory *iface, LPUNKNOWN outer, REFIID riid, + LPVOID *obj ) +{ + struct factory *factory = impl_from_IClassFactory( iface ); + IUnknown *unk; + HRESULT hr; + + TRACE( "%p, %s, %p\n", outer, debugstr_guid(riid), obj ); + + *obj = NULL; + if (outer) return CLASS_E_NOAGGREGATION; + + hr = factory->fnCreateInstance( (LPVOID *)&unk ); + if (FAILED( hr )) + return hr; + + hr = IUnknown_QueryInterface( unk, riid, obj ); + IUnknown_Release( unk ); + return hr; +} + +static HRESULT WINAPI factory_LockServer( IClassFactory *iface, BOOL lock ) +{ + FIXME( "%p, %d\n", iface, lock ); + return S_OK; +} + +static const struct IClassFactoryVtbl factory_vtbl = +{ + factory_QueryInterface, + factory_AddRef, + factory_Release, + factory_CreateInstance, + factory_LockServer +}; + +static struct factory swbem_locator_cf = { { &factory_vtbl }, SWbemLocator_create }; +static struct factory winmgmts_cf = { { &factory_vtbl }, WinMGMTS_create }; + +BOOL WINAPI DllMain( HINSTANCE hinst, DWORD reason, LPVOID reserved ) +{ + + switch (reason) + { + case DLL_WINE_PREATTACH: + return FALSE; /* prefer native version */ + case DLL_PROCESS_ATTACH: + instance = hinst; + DisableThreadLibraryCalls( hinst ); + break; + } + return TRUE; +} + +HRESULT WINAPI DllGetClassObject( REFCLSID rclsid, REFIID iid, LPVOID *obj ) +{ + IClassFactory *cf = NULL; + + TRACE( "%s, %s, %p\n", debugstr_guid(rclsid), debugstr_guid(iid), obj ); + + if (IsEqualGUID( rclsid, &CLSID_SWbemLocator )) + cf = &swbem_locator_cf.IClassFactory_iface; + else if (IsEqualGUID( rclsid, &CLSID_WinMGMTS )) + cf = &winmgmts_cf.IClassFactory_iface; + else + return CLASS_E_CLASSNOTAVAILABLE; + + return IClassFactory_QueryInterface( cf, iid, obj ); +} + +/*********************************************************************** + * DllCanUnloadNow (WBEMDISP.@) + */ +HRESULT WINAPI DllCanUnloadNow(void) +{ + return S_FALSE; +} + +/*********************************************************************** + * DllRegisterServer (WBEMDISP.@) + */ +HRESULT WINAPI DllRegisterServer(void) +{ + return __wine_register_resources( instance ); +} + +/*********************************************************************** + * DllUnregisterServer (WBEMDISP.@) + */ +HRESULT WINAPI DllUnregisterServer(void) +{ + return __wine_unregister_resources( instance ); +} diff --git a/reactos/dll/win32/wbemdisp/wbemdisp.rc b/reactos/dll/win32/wbemdisp/wbemdisp.rc new file mode 100644 index 00000000000..36ac6ff4906 --- /dev/null +++ b/reactos/dll/win32/wbemdisp/wbemdisp.rc @@ -0,0 +1,3 @@ +1 WINE_REGISTRY "wbemdisp_classes.rgs" +2 WINE_REGISTRY "wbemdisp_tlb.rgs" +1 TYPELIB "wbemdisp_tlb.tlb" diff --git a/reactos/dll/win32/wbemdisp/wbemdisp.spec b/reactos/dll/win32/wbemdisp/wbemdisp.spec new file mode 100644 index 00000000000..b16365d0c9f --- /dev/null +++ b/reactos/dll/win32/wbemdisp/wbemdisp.spec @@ -0,0 +1,4 @@ +@ stdcall -private DllCanUnloadNow() +@ stdcall -private DllGetClassObject(ptr ptr ptr) +@ stdcall -private DllRegisterServer() +@ stdcall -private DllUnregisterServer() diff --git a/reactos/dll/win32/wbemdisp/wbemdisp_classes.idl b/reactos/dll/win32/wbemdisp/wbemdisp_classes.idl new file mode 100644 index 00000000000..0cea2c8b895 --- /dev/null +++ b/reactos/dll/win32/wbemdisp/wbemdisp_classes.idl @@ -0,0 +1,29 @@ +/* + * COM Classes for wbemdisp + * + * Copyright 2013 Hans Leidekker for CodeWeavers + * + * 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 + */ + +#pragma makedep register + +[ + threading(apartment), + uuid(172bddf8-ceea-11d1-8b05-00600806d9b6), + progid("WINMGMTS.1"), + vi_progid("WINMGMTS") +] +coclass WinMGMTS { interface IParseDisplayName; } diff --git a/reactos/dll/win32/wbemdisp/wbemdisp_classes.rgs b/reactos/dll/win32/wbemdisp/wbemdisp_classes.rgs new file mode 100644 index 00000000000..6c9015e833c --- /dev/null +++ b/reactos/dll/win32/wbemdisp/wbemdisp_classes.rgs @@ -0,0 +1,24 @@ +HKCR +{ + NoRemove Interface + { + } + NoRemove CLSID + { + '{172BDDF8-CEEA-11D1-8B05-00600806D9B6}' = s 'WinMGMTS' + { + InprocServer32 = s '%MODULE%' { val ThreadingModel = s 'Apartment' } + ProgId = s 'WINMGMTS.1' + VersionIndependentProgId = s 'WINMGMTS' + } + } + 'WINMGMTS.1' = s 'WinMGMTS' + { + CLSID = s '{172BDDF8-CEEA-11D1-8B05-00600806D9B6}' + } + 'WINMGMTS' = s 'WinMGMTS' + { + CLSID = s '{172BDDF8-CEEA-11D1-8B05-00600806D9B6}' + CurVer = s 'WINMGMTS.1' + } +} diff --git a/reactos/dll/win32/wbemdisp/wbemdisp_private.h b/reactos/dll/win32/wbemdisp/wbemdisp_private.h new file mode 100644 index 00000000000..e4ae2cb6588 --- /dev/null +++ b/reactos/dll/win32/wbemdisp/wbemdisp_private.h @@ -0,0 +1,56 @@ +/* + * Copyright 2013 Hans Leidekker for CodeWeavers + * + * 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 + */ + +#ifndef _WBEMDISP_PRIVATE_H_ +#define _WBEMDISP_PRIVATE_H_ + +#include + +#include + +#define WIN32_NO_STATUS +#define _INC_WINDOWS +#define COM_NO_WINDOWS_H + +#define COBJMACROS + +#include +#include +#include +#include +#include + +#include +#include + +WINE_DEFAULT_DEBUG_CHANNEL(wbemdisp); + +HRESULT SWbemLocator_create(LPVOID *) DECLSPEC_HIDDEN; + +static void *heap_alloc( size_t len ) __WINE_ALLOC_SIZE(1); +static inline void *heap_alloc( size_t len ) +{ + return HeapAlloc( GetProcessHeap(), 0, len ); +} + +static inline BOOL heap_free( void *mem ) +{ + return HeapFree( GetProcessHeap(), 0, mem ); +} + +#endif /* _WBEMDISP_PRIVATE_H_ */ diff --git a/reactos/dll/win32/wbemdisp/wbemdisp_tlb.idl b/reactos/dll/win32/wbemdisp/wbemdisp_tlb.idl new file mode 100644 index 00000000000..9174a2ca6cc --- /dev/null +++ b/reactos/dll/win32/wbemdisp/wbemdisp_tlb.idl @@ -0,0 +1,23 @@ +/* + * Typelib for wbemdisp + * + * Copyright 2013 Hans Leidekker for CodeWeavers + * + * 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 + */ + +#pragma makedep regtypelib + +#include "wbemdisp.idl" diff --git a/reactos/dll/win32/wbemdisp/wbemdisp_tlb.rgs b/reactos/dll/win32/wbemdisp/wbemdisp_tlb.rgs new file mode 100644 index 00000000000..f24e5417d29 --- /dev/null +++ b/reactos/dll/win32/wbemdisp/wbemdisp_tlb.rgs @@ -0,0 +1,139 @@ +HKCR +{ + NoRemove Typelib + { + NoRemove '{565783C6-CB41-11D1-8B02-00600806D9B6}' + { + '1.2' = s 'Microsoft WMI Scripting V1.2 Library' + { + '0' { win32 = s '%MODULE%' } + FLAGS = s '0' + } + } + } + NoRemove Interface + { + '{27D54D92-0EBE-11D2-8B22-00600806D9B6}' = s 'ISWbemEventSource' + { + ProxyStubClsid = s '{00020424-0000-0000-C000-000000000046}' + ProxyStubClsid32 = s '{00020424-0000-0000-C000-000000000046}' + TypeLib = s '{565783C6-CB41-11D1-8B02-00600806D9B6}' { val Version = s '1.2' } + } + '{76A6415B-CB41-11D1-8B02-00600806D9B6}' = s 'ISWbemLocator' + { + ProxyStubClsid = s '{00020424-0000-0000-C000-000000000046}' + ProxyStubClsid32 = s '{00020424-0000-0000-C000-000000000046}' + TypeLib = s '{565783C6-CB41-11D1-8B02-00600806D9B6}' { val Version = s '1.2' } + } + '{422E8E90-D955-11D1-8B09-00600806D9B6}' = s 'ISWbemMethod' + { + ProxyStubClsid = s '{00020424-0000-0000-C000-000000000046}' + ProxyStubClsid32 = s '{00020424-0000-0000-C000-000000000046}' + TypeLib = s '{565783C6-CB41-11D1-8B02-00600806D9B6}' { val Version = s '1.2' } + } + '{C93BA292-D955-11D1-8B09-00600806D9B6}' = s 'ISWbemMethodSet' + { + ProxyStubClsid = s '{00020424-0000-0000-C000-000000000046}' + ProxyStubClsid32 = s '{00020424-0000-0000-C000-000000000046}' + TypeLib = s '{565783C6-CB41-11D1-8B02-00600806D9B6}' { val Version = s '1.2' } + } + '{76A64164-CB41-11D1-8B02-00600806D9B6}' = s 'ISWbemNamedValue' + { + ProxyStubClsid = s '{00020424-0000-0000-C000-000000000046}' + ProxyStubClsid32 = s '{00020424-0000-0000-C000-000000000046}' + TypeLib = s '{565783C6-CB41-11D1-8B02-00600806D9B6}' { val Version = s '1.2' } + } + '{CF2376EA-CE8C-11D1-8B05-00600806D9B6}' = s 'ISWbemNamedValueSet' + { + ProxyStubClsid = s '{00020424-0000-0000-C000-000000000046}' + ProxyStubClsid32 = s '{00020424-0000-0000-C000-000000000046}' + TypeLib = s '{565783C6-CB41-11D1-8B02-00600806D9B6}' { val Version = s '1.2' } + } + '{76A6415A-CB41-11D1-8B02-00600806D9B6}' = s 'ISWbemObject' + { + ProxyStubClsid = s '{00020424-0000-0000-C000-000000000046}' + ProxyStubClsid32 = s '{00020424-0000-0000-C000-000000000046}' + TypeLib = s '{565783C6-CB41-11D1-8B02-00600806D9B6}' { val Version = s '1.2' } + } + '{5791BC27-CE9C-11D1-97BF-0000F81E849C}' = s 'ISWbemObjectPath' + { + ProxyStubClsid = s '{00020424-0000-0000-C000-000000000046}' + ProxyStubClsid32 = s '{00020424-0000-0000-C000-000000000046}' + TypeLib = s '{565783C6-CB41-11D1-8B02-00600806D9B6}' { val Version = s '1.2' } + } + '{76A6415F-CB41-11D1-8B02-00600806D9B6}' = s 'ISWbemObjectSet' + { + ProxyStubClsid = s '{00020424-0000-0000-C000-000000000046}' + ProxyStubClsid32 = s '{00020424-0000-0000-C000-000000000046}' + TypeLib = s '{565783C6-CB41-11D1-8B02-00600806D9B6}' { val Version = s '1.2' } + } + '{26EE67BD-5804-11D2-8B4A-00600806D9B6}' = s 'ISWbemPrivilege' + { + ProxyStubClsid = s '{00020424-0000-0000-C000-000000000046}' + ProxyStubClsid32 = s '{00020424-0000-0000-C000-000000000046}' + TypeLib = s '{565783C6-CB41-11D1-8B02-00600806D9B6}' { val Version = s '1.2' } + } + '{26EE67BF-5804-11D2-8B4A-00600806D9B6}' = s 'ISWbemPrivilegeSet' + { + ProxyStubClsid = s '{00020424-0000-0000-C000-000000000046}' + ProxyStubClsid32 = s '{00020424-0000-0000-C000-000000000046}' + TypeLib = s '{565783C6-CB41-11D1-8B02-00600806D9B6}' { val Version = s '1.2' } + } + '{1A388F98-D4BA-11D1-8B09-00600806D9B6}' = s 'ISWbemProperty' + { + ProxyStubClsid = s '{00020424-0000-0000-C000-000000000046}' + ProxyStubClsid32 = s '{00020424-0000-0000-C000-000000000046}' + TypeLib = s '{565783C6-CB41-11D1-8B02-00600806D9B6}' { val Version = s '1.2' } + } + '{DEA0A7B2-D4BA-11D1-8B09-00600806D9B6}' = s 'ISWbemPropertySet' + { + ProxyStubClsid = s '{00020424-0000-0000-C000-000000000046}' + ProxyStubClsid32 = s '{00020424-0000-0000-C000-000000000046}' + TypeLib = s '{565783C6-CB41-11D1-8B02-00600806D9B6}' { val Version = s '1.2' } + } + '{79B05932-D3B7-11D1-8B06-00600806D9B6}' = s 'ISWbemQualifier' + { + ProxyStubClsid = s '{00020424-0000-0000-C000-000000000046}' + ProxyStubClsid32 = s '{00020424-0000-0000-C000-000000000046}' + TypeLib = s '{565783C6-CB41-11D1-8B02-00600806D9B6}' { val Version = s '1.2' } + } + '{9B16ED16-D3DF-11D1-8B08-00600806D9B6}' = s 'ISWbemQualifierSet' + { + ProxyStubClsid = s '{00020424-0000-0000-C000-000000000046}' + ProxyStubClsid32 = s '{00020424-0000-0000-C000-000000000046}' + TypeLib = s '{565783C6-CB41-11D1-8B02-00600806D9B6}' { val Version = s '1.2' } + } + '{B54D66E6-2287-11D2-8B33-00600806D9B6}' = s 'ISWbemSecurity' + { + ProxyStubClsid = s '{00020424-0000-0000-C000-000000000046}' + ProxyStubClsid32 = s '{00020424-0000-0000-C000-000000000046}' + TypeLib = s '{565783C6-CB41-11D1-8B02-00600806D9B6}' { val Version = s '1.2' } + } + '{76A6415C-CB41-11D1-8B02-00600806D9B6}' = s 'ISWbemServices' + { + ProxyStubClsid = s '{00020424-0000-0000-C000-000000000046}' + ProxyStubClsid32 = s '{00020424-0000-0000-C000-000000000046}' + TypeLib = s '{565783C6-CB41-11D1-8B02-00600806D9B6}' { val Version = s '1.2' } + } + } + NoRemove CLSID + { + '{76A64158-CB41-11D1-8B02-00600806D9B6}' = s 'SWbemLocator' + { + InprocServer32 = s '%MODULE%' { val ThreadingModel = s 'Apartment' } + ProgId = s 'WbemScripting.SWbemLocator.1' + TypeLib = s '{565783C6-CB41-11D1-8B02-00600806D9B6}' + Version = s '1.2' + VersionIndependentProgId = s 'WbemScripting.SWbemLocator' + } + } + 'WbemScripting.SWbemLocator.1' = s 'SWbemLocator' + { + CLSID = s '{76A64158-CB41-11D1-8B02-00600806D9B6}' + } + 'WbemScripting.SWbemLocator' = s 'SWbemLocator' + { + CLSID = s '{76A64158-CB41-11D1-8B02-00600806D9B6}' + CurVer = s 'WbemScripting.SWbemLocator.1' + } +} diff --git a/reactos/dll/win32/wbemprox/CMakeLists.txt b/reactos/dll/win32/wbemprox/CMakeLists.txt new file mode 100644 index 00000000000..b2495e176db --- /dev/null +++ b/reactos/dll/win32/wbemprox/CMakeLists.txt @@ -0,0 +1,37 @@ + +remove_definitions(-D_WIN32_WINNT=0x502) +add_definitions(-D_WIN32_WINNT=0x600) + +add_definitions(-D__WINESRC__) +include_directories(BEFORE ${REACTOS_SOURCE_DIR}/sdk/include/reactos/wine) +spec2def(wbemprox.dll wbemprox.spec) + +list(APPEND SOURCE + builtin.c + class.c + main.c + process.c + qualifier.c + query.c + reg.c + security.c + service.c + services.c + table.c + wbemlocator.c + wql.tab.c + wbemprox_private.h) + +add_library(wbemprox SHARED + ${SOURCE} + guid.c + wbemprox.rc + ${CMAKE_CURRENT_BINARY_DIR}/wbemprox.def) + +set_source_files_properties(wbemprox.rc PROPERTIES OBJECT_DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/wbemprox.rgs) +set_module_type(wbemprox win32dll) +target_link_libraries(wbemprox uuid wine) +add_importlibs(wbemprox iphlpapi oleaut32 advapi32 user32 gdi32 version winspool ws2_32 rpcrt4 msvcrt kernel32 ntdll) +add_dependencies(wbemprox d3d_idl_headers) +add_pch(wbemprox wbemprox_private.h SOURCE) +add_cd_file(TARGET wbemprox DESTINATION reactos/system32/wbem FOR all) diff --git a/reactos/dll/win32/wbemprox/builtin.c b/reactos/dll/win32/wbemprox/builtin.c new file mode 100644 index 00000000000..31b8a10b422 --- /dev/null +++ b/reactos/dll/win32/wbemprox/builtin.c @@ -0,0 +1,3157 @@ +/* + * Copyright 2012 Hans Leidekker for CodeWeavers + * + * 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 "wbemprox_private.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static const WCHAR class_baseboardW[] = + {'W','i','n','3','2','_','B','a','s','e','B','o','a','r','d',0}; +static const WCHAR class_biosW[] = + {'W','i','n','3','2','_','B','I','O','S',0}; +static const WCHAR class_cdromdriveW[] = + {'W','i','n','3','2','_','C','D','R','O','M','D','r','i','v','e',0}; +static const WCHAR class_compsysW[] = + {'W','i','n','3','2','_','C','o','m','p','u','t','e','r','S','y','s','t','e','m',0}; +static const WCHAR class_compsysproductW[] = + {'W','i','n','3','2','_','C','o','m','p','u','t','e','r','S','y','s','t','e','m','P','r','o','d','u','c','t',0}; +static const WCHAR class_datafileW[] = + {'C','I','M','_','D','a','t','a','F','i','l','e',0}; +static const WCHAR class_desktopmonitorW[] = + {'W','i','n','3','2','_','D','e','s','k','t','o','p','M','o','n','i','t','o','r',0}; +static const WCHAR class_directoryW[] = + {'W','i','n','3','2','_','D','i','r','e','c','t','o','r','y',0}; +static const WCHAR class_diskdriveW[] = + {'W','i','n','3','2','_','D','i','s','k','D','r','i','v','e',0}; +static const WCHAR class_diskpartitionW[] = + {'W','i','n','3','2','_','D','i','s','k','P','a','r','t','i','t','i','o','n',0}; +static const WCHAR class_logicaldiskW[] = + {'W','i','n','3','2','_','L','o','g','i','c','a','l','D','i','s','k',0}; +static const WCHAR class_logicaldisk2W[] = + {'C','I','M','_','L','o','g','i','c','a','l','D','i','s','k',0}; +static const WCHAR class_networkadapterW[] = + {'W','i','n','3','2','_','N','e','t','w','o','r','k','A','d','a','p','t','e','r',0}; +static const WCHAR class_networkadapterconfigW[] = + {'W','i','n','3','2','_','N','e','t','w','o','r','k','A','d','a','p','t','e','r', + 'C','o','n','f','i','g','u','r','a','t','i','o','n',0}; +static const WCHAR class_osW[] = + {'W','i','n','3','2','_','O','p','e','r','a','t','i','n','g','S','y','s','t','e','m',0}; +static const WCHAR class_paramsW[] = + {'_','_','P','A','R','A','M','E','T','E','R','S',0}; +static const WCHAR class_physicalmediaW[] = + {'W','i','n','3','2','_','P','h','y','s','i','c','a','l','M','e','d','i','a',0}; +static const WCHAR class_physicalmemoryW[] = + {'W','i','n','3','2','_','P','h','y','s','i','c','a','l','M','e','m','o','r','y',0}; +static const WCHAR class_printerW[] = + {'W','i','n','3','2','_','P','r','i','n','t','e','r',0}; +static const WCHAR class_process_getowner_outW[] = + {'_','_','W','I','N','3','2','_','P','R','O','C','E','S','S','_','G','E','T','O','W', + 'N','E','R','_','O','U','T',0}; +static const WCHAR class_processorW[] = + {'W','i','n','3','2','_','P','r','o','c','e','s','s','o','r',0}; +static const WCHAR class_processor2W[] = + {'C','I','M','_','P','r','o','c','e','s','s','o','r',0}; +static const WCHAR class_qualifiersW[] = + {'_','_','Q','U','A','L','I','F','I','E','R','S',0}; +static const WCHAR class_sidW[] = + {'W','i','n','3','2','_','S','I','D',0}; +static const WCHAR class_sounddeviceW[] = + {'W','i','n','3','2','_','S','o','u','n','d','D','e','v','i','c','e',0}; +static const WCHAR class_systemenclosureW[] = + {'W','i','n','3','2','_','S','y','s','t','e','m','E','n','c','l','o','s','u','r','e',0}; +static const WCHAR class_videocontrollerW[] = + {'W','i','n','3','2','_','V','i','d','e','o','C','o','n','t','r','o','l','l','e','r',0}; + +static const WCHAR prop_accountnameW[] = + {'A','c','c','o','u','n','t','N','a','m','e',0}; +static const WCHAR prop_acceptpauseW[] = + {'A','c','c','e','p','t','P','a','u','s','e',0}; +static const WCHAR prop_acceptstopW[] = + {'A','c','c','e','p','t','S','t','o','p',0}; +static const WCHAR prop_accessmaskW[] = + {'A','c','c','e','s','s','M','a','s','k',0}; +static const WCHAR prop_adapterdactypeW[] = + {'A','d','a','p','t','e','r','D','A','C','T','y','p','e',0}; +static const WCHAR prop_adapterramW[] = + {'A','d','a','p','t','e','r','R','A','M',0}; +static const WCHAR prop_adaptertypeW[] = + {'A','d','a','p','t','e','r','T','y','p','e',0}; +static const WCHAR prop_addresswidthW[] = + {'A','d','d','r','e','s','s','W','i','d','t','h',0}; +static const WCHAR prop_attributesW[] = + {'A','t','t','r','i','b','u','t','e','s',0}; +static const WCHAR prop_availabilityW[] = + {'A','v','a','i','l','a','b','i','l','i','t','y',0}; +static const WCHAR prop_binaryrepresentationW[] = + {'B','i','n','a','r','y','R','e','p','r','e','s','e','n','t','a','t','i','o','n',0}; +static const WCHAR prop_bootableW[] = + {'B','o','o','t','a','b','l','e',0}; +static const WCHAR prop_bootpartitionW[] = + {'B','o','o','t','P','a','r','t','i','t','i','o','n',0}; +static const WCHAR prop_buildnumberW[] = + {'B','u','i','l','d','N','u','m','b','e','r',0}; +static const WCHAR prop_capacityW[] = + {'C','a','p','a','c','i','t','y',0}; +static const WCHAR prop_captionW[] = + {'C','a','p','t','i','o','n',0}; +static const WCHAR prop_chassistypesW[] = + {'C','h','a','s','s','i','s','T','y','p','e','s',0}; +static const WCHAR prop_classW[] = + {'C','l','a','s','s',0}; +static const WCHAR prop_codesetW[] = + {'C','o','d','e','S','e','t',0}; +static const WCHAR prop_commandlineW[] = + {'C','o','m','m','a','n','d','L','i','n','e',0}; +static const WCHAR prop_countrycodeW[] = + {'C','o','u','n','t','r','y','C','o','d','e',0}; +static const WCHAR prop_cpustatusW[] = + {'C','p','u','S','t','a','t','u','s',0}; +static const WCHAR prop_csdversionW[] = + {'C','S','D','V','e','r','s','i','o','n',0}; +static const WCHAR prop_currentbitsperpixelW[] = + {'C','u','r','r','e','n','t','B','i','t','s','P','e','r','P','i','x','e','l',0}; +static const WCHAR prop_currentclockspeedW[] = + {'C','u','r','r','e','n','t','C','l','o','c','k','S','p','e','e','d',0}; +static const WCHAR prop_currenthorizontalresW[] = + {'C','u','r','r','e','n','t','H','o','r','i','z','o','n','t','a','l','R','e','s','o','l','u','t','i','o','n',0}; +static const WCHAR prop_currentrefreshrateW[] = + {'C','u','r','r','e','n','t','R','e','f','r','e','s','h','R','a','t','e',0}; +static const WCHAR prop_currentscanmodeW[] = + {'C','u','r','r','e','n','t','S','c','a','n','M','o','d','e',0}; +static const WCHAR prop_currentverticalresW[] = + {'C','u','r','r','e','n','t','V','e','r','t','i','c','a','l','R','e','s','o','l','u','t','i','o','n',0}; +static const WCHAR prop_datawidthW[] = + {'D','a','t','a','W','i','d','t','h',0}; +static const WCHAR prop_defaultipgatewayW[] = + {'D','e','f','a','u','l','t','I','P','G','a','t','e','w','a','y',0}; +static const WCHAR prop_defaultvalueW[] = + {'D','e','f','a','u','l','t','V','a','l','u','e',0}; +static const WCHAR prop_descriptionW[] = + {'D','e','s','c','r','i','p','t','i','o','n',0}; +static const WCHAR prop_deviceidW[] = + {'D','e','v','i','c','e','I','d',0}; +static const WCHAR prop_dhcpenabledW[] = + {'D','H','C','P','E','n','a','b','l','e','d',0}; +static const WCHAR prop_directionW[] = + {'D','i','r','e','c','t','i','o','n',0}; +static const WCHAR prop_displaynameW[] = + {'D','i','s','p','l','a','y','N','a','m','e',0}; +static const WCHAR prop_diskindexW[] = + {'D','i','s','k','I','n','d','e','x',0}; +static const WCHAR prop_dnshostnameW[] = + {'D','N','S','H','o','s','t','N','a','m','e',0}; +static const WCHAR prop_dnsserversearchorderW[] = + {'D','N','S','S','e','r','v','e','r','S','e','a','r','c','h','O','r','d','e','r',0}; +static const WCHAR prop_domainW[] = + {'D','o','m','a','i','n',0}; +static const WCHAR prop_domainroleW[] = + {'D','o','m','a','i','n','R','o','l','e',0}; +static const WCHAR prop_driveW[] = + {'D','r','i','v','e',0}; +static const WCHAR prop_drivernameW[] = + {'D','r','i','v','e','r','N','a','m','e',0}; +static const WCHAR prop_driverversionW[] = + {'D','r','i','v','e','r','V','e','r','s','i','o','n',0}; +static const WCHAR prop_drivetypeW[] = + {'D','r','i','v','e','T','y','p','e',0}; +static const WCHAR prop_familyW[] = + {'F','a','m','i','l','y',0}; +static const WCHAR prop_filesystemW[] = + {'F','i','l','e','S','y','s','t','e','m',0}; +static const WCHAR prop_flavorW[] = + {'F','l','a','v','o','r',0}; +static const WCHAR prop_freespaceW[] = + {'F','r','e','e','S','p','a','c','e',0}; +static const WCHAR prop_handleW[] = + {'H','a','n','d','l','e',0}; +static const WCHAR prop_horizontalresolutionW[] = + {'H','o','r','i','z','o','n','t','a','l','R','e','s','o','l','u','t','i','o','n',0}; +static const WCHAR prop_idW[] = + {'I','D',0}; +static const WCHAR prop_identificationcodeW[] = + {'I','d','e','n','t','i','f','i','c','a','t','i','o','n','C','o','d','e',0}; +static const WCHAR prop_identifyingnumberW[] = + {'I','d','e','n','t','i','f','y','i','n','g','N','u','m','b','e','r',0}; +static const WCHAR prop_indexW[] = + {'I','n','d','e','x',0}; +static const WCHAR prop_installdateW[] = + {'I','n','s','t','a','l','l','D','a','t','e',0}; +static const WCHAR prop_interfaceindexW[] = + {'I','n','t','e','r','f','a','c','e','I','n','d','e','x',0}; +static const WCHAR prop_interfacetypeW[] = + {'I','n','t','e','r','f','a','c','e','T','y','p','e',0}; +static const WCHAR prop_intvalueW[] = + {'I','n','t','e','g','e','r','V','a','l','u','e',0}; +static const WCHAR prop_ipconnectionmetricW[] = + {'I','P','C','o','n','n','e','c','t','i','o','n','M','e','t','r','i','c',0}; +static const WCHAR prop_ipenabledW[] = + {'I','P','E','n','a','b','l','e','d',0}; +static const WCHAR prop_lastbootuptimeW[] = + {'L','a','s','t','B','o','o','t','U','p','T','i','m','e',0}; +static const WCHAR prop_localW[] = + {'L','o','c','a','l',0}; +static const WCHAR prop_localdatetimeW[] = + {'L','o','c','a','l','D','a','t','e','T','i','m','e',0}; +static const WCHAR prop_localeW[] = + {'L','o','c','a','l','e',0}; +static const WCHAR prop_locationW[] = + {'L','o','c','a','t','i','o','n',0}; +static const WCHAR prop_lockpresentW[] = + {'L','o','c','k','P','r','e','s','e','n','t',0}; +static const WCHAR prop_macaddressW[] = + {'M','A','C','A','d','d','r','e','s','s',0}; +static const WCHAR prop_manufacturerW[] = + {'M','a','n','u','f','a','c','t','u','r','e','r',0}; +static const WCHAR prop_maxclockspeedW[] = + {'M','a','x','C','l','o','c','k','S','p','e','e','d',0}; +static const WCHAR prop_mediatypeW[] = + {'M','e','d','i','a','T','y','p','e',0}; +static const WCHAR prop_memberW[] = + {'M','e','m','b','e','r',0}; +static const WCHAR prop_methodW[] = + {'M','e','t','h','o','d',0}; +static const WCHAR prop_modelW[] = + {'M','o','d','e','l',0}; +static const WCHAR prop_netconnectionstatusW[] = + {'N','e','t','C','o','n','n','e','c','t','i','o','n','S','t','a','t','u','s',0}; +static const WCHAR prop_networkW[] = + {'N','e','t','w','o','r','k',0}; +static const WCHAR prop_numcoresW[] = + {'N','u','m','b','e','r','O','f','C','o','r','e','s',0}; +static const WCHAR prop_numlogicalprocessorsW[] = + {'N','u','m','b','e','r','O','f','L','o','g','i','c','a','l','P','r','o','c','e','s','s','o','r','s',0}; +static const WCHAR prop_numprocessorsW[] = + {'N','u','m','b','e','r','O','f','P','r','o','c','e','s','s','o','r','s',0}; +static const WCHAR prop_osarchitectureW[] = + {'O','S','A','r','c','h','i','t','e','c','t','u','r','e',0}; +static const WCHAR prop_oslanguageW[] = + {'O','S','L','a','n','g','u','a','g','e',0}; +static const WCHAR prop_osproductsuiteW[] = + {'O','S','P','r','o','d','u','c','t','S','u','i','t','e',0}; +static const WCHAR prop_ostypeW[] = + {'O','S','T','y','p','e',0}; +static const WCHAR prop_parameterW[] = + {'P','a','r','a','m','e','t','e','r',0}; +static const WCHAR prop_physicaladapterW[] = + {'P','h','y','s','i','c','a','l','A','d','a','p','t','e','r',0}; +static const WCHAR prop_pixelsperxlogicalinchW[] = + {'P','i','x','e','l','s','P','e','r','X','L','o','g','i','c','a','l','I','n','c','h',0}; +static const WCHAR prop_pnpdeviceidW[] = + {'P','N','P','D','e','v','i','c','e','I','D',0}; +static const WCHAR prop_portnameW[] = + {'P','o','r','t','N','a','m','e',0}; +static const WCHAR prop_pprocessidW[] = + {'P','a','r','e','n','t','P','r','o','c','e','s','s','I','D',0}; +static const WCHAR prop_primaryW[] = + {'P','r','i','m','a','r','y',0}; +static const WCHAR prop_processidW[] = + {'P','r','o','c','e','s','s','I','D',0}; +static const WCHAR prop_processoridW[] = + {'P','r','o','c','e','s','s','o','r','I','d',0}; +static const WCHAR prop_processortypeW[] = + {'P','r','o','c','e','s','s','o','r','T','y','p','e',0}; +static const WCHAR prop_productW[] = + {'P','r','o','d','u','c','t',0}; +static const WCHAR prop_productnameW[] = + {'P','r','o','d','u','c','t','N','a','m','e',0}; +static const WCHAR prop_referenceddomainnameW[] = + {'R','e','f','e','r','e','n','c','e','d','D','o','m','a','i','n','N','a','m','e',0}; +static const WCHAR prop_releasedateW[] = + {'R','e','l','e','a','s','e','D','a','t','e',0}; +static const WCHAR prop_serialnumberW[] = + {'S','e','r','i','a','l','N','u','m','b','e','r',0}; +static const WCHAR prop_servicepackmajorW[] = + {'S','e','r','v','i','c','e','P','a','c','k','M','a','j','o','r','V','e','r','s','i','o','n',0}; +static const WCHAR prop_servicepackminorW[] = + {'S','e','r','v','i','c','e','P','a','c','k','M','i','n','o','r','V','e','r','s','i','o','n',0}; +static const WCHAR prop_servicetypeW[] = + {'S','e','r','v','i','c','e','T','y','p','e',0}; +static const WCHAR prop_settingidW[] = + {'S','e','t','t','i','n','g','I','D',0}; +static const WCHAR prop_smbiosbiosversionW[] = + {'S','M','B','I','O','S','B','I','O','S','V','e','r','s','i','o','n',0}; +static const WCHAR prop_startmodeW[] = + {'S','t','a','r','t','M','o','d','e',0}; +static const WCHAR prop_sidW[] = + {'S','I','D',0}; +static const WCHAR prop_sidlengthW[] = + {'S','i','d','L','e','n','g','t','h',0}; +static const WCHAR prop_sizeW[] = + {'S','i','z','e',0}; +static const WCHAR prop_speedW[] = + {'S','p','e','e','d',0}; +static const WCHAR prop_startingoffsetW[] = + {'S','t','a','r','t','i','n','g','O','f','f','s','e','t',0}; +static const WCHAR prop_stateW[] = + {'S','t','a','t','e',0}; +static const WCHAR prop_statusinfoW[] = + {'S','t','a','t','u','s','I','n','f','o',0}; +static const WCHAR prop_strvalueW[] = + {'S','t','r','i','n','g','V','a','l','u','e',0}; +static const WCHAR prop_suitemaskW[] = + {'S','u','i','t','e','M','a','s','k',0}; +static const WCHAR prop_systemdirectoryW[] = + {'S','y','s','t','e','m','D','i','r','e','c','t','o','r','y',0}; +static const WCHAR prop_systemnameW[] = + {'S','y','s','t','e','m','N','a','m','e',0}; +static const WCHAR prop_tagW[] = + {'T','a','g',0}; +static const WCHAR prop_threadcountW[] = + {'T','h','r','e','a','d','C','o','u','n','t',0}; +static const WCHAR prop_totalphysicalmemoryW[] = + {'T','o','t','a','l','P','h','y','s','i','c','a','l','M','e','m','o','r','y',0}; +static const WCHAR prop_totalvisiblememorysizeW[] = + {'T','o','t','a','l','V','i','s','i','b','l','e','M','e','m','o','r','y','S','i','z','e',0}; +static const WCHAR prop_typeW[] = + {'T','y','p','e',0}; +static const WCHAR prop_uniqueidW[] = + {'U','n','i','q','u','e','I','d',0}; +static const WCHAR prop_usernameW[] = + {'U','s','e','r','N','a','m','e',0}; +static const WCHAR prop_uuidW[] = + {'U','U','I','D',0}; +static const WCHAR prop_varianttypeW[] = + {'V','a','r','i','a','n','t','T','y','p','e',0}; +static const WCHAR prop_versionW[] = + {'V','e','r','s','i','o','n',0}; +static const WCHAR prop_videoarchitectureW[] = + {'V','i','d','e','o','A','r','c','h','i','t','e','c','t','u','r','e',0}; +static const WCHAR prop_videomemorytypeW[] = + {'V','i','d','e','o','M','e','m','o','r','y','T','y','p','e',0}; +static const WCHAR prop_videomodedescriptionW[] = + {'V','i','d','e','o','M','o','d','e','D','e','s','c','r','i','p','t','i','o','n',0}; +static const WCHAR prop_videoprocessorW[] = + {'V','i','d','e','o','P','r','o','c','e','s','s','o','r',0}; +static const WCHAR prop_volumenameW[] = + {'V','o','l','u','m','e','N','a','m','e',0}; +static const WCHAR prop_volumeserialnumberW[] = + {'V','o','l','u','m','e','S','e','r','i','a','l','N','u','m','b','e','r',0}; +static const WCHAR prop_workingsetsizeW[] = + {'W','o','r','k','i','n','g','S','e','t','S','i','z','e',0}; + +/* column definitions must be kept in sync with record structures below */ +static const struct column col_baseboard[] = +{ + { prop_manufacturerW, CIM_STRING }, + { prop_modelW, CIM_STRING }, + { prop_nameW, CIM_STRING }, + { prop_productW, CIM_STRING }, + { prop_serialnumberW, CIM_STRING }, + { prop_tagW, CIM_STRING|COL_FLAG_KEY }, + { prop_versionW, CIM_STRING } +}; +static const struct column col_bios[] = +{ + { prop_descriptionW, CIM_STRING }, + { prop_identificationcodeW, CIM_STRING }, + { prop_manufacturerW, CIM_STRING }, + { prop_nameW, CIM_STRING }, + { prop_releasedateW, CIM_DATETIME }, + { prop_serialnumberW, CIM_STRING }, + { prop_smbiosbiosversionW, CIM_STRING }, + { prop_versionW, CIM_STRING|COL_FLAG_KEY } +}; +static const struct column col_cdromdrive[] = +{ + { prop_deviceidW, CIM_STRING|COL_FLAG_KEY }, + { prop_driveW, CIM_STRING|COL_FLAG_DYNAMIC }, + { prop_mediatypeW, CIM_STRING }, + { prop_nameW, CIM_STRING }, + { prop_pnpdeviceidW, CIM_STRING } +}; +static const struct column col_compsys[] = +{ + { prop_descriptionW, CIM_STRING }, + { prop_domainW, CIM_STRING }, + { prop_domainroleW, CIM_UINT16, VT_I4 }, + { prop_manufacturerW, CIM_STRING }, + { prop_modelW, CIM_STRING }, + { prop_nameW, CIM_STRING|COL_FLAG_DYNAMIC }, + { prop_numlogicalprocessorsW, CIM_UINT32, VT_I4 }, + { prop_numprocessorsW, CIM_UINT32, VT_I4 }, + { prop_totalphysicalmemoryW, CIM_UINT64 }, + { prop_usernameW, CIM_STRING|COL_FLAG_DYNAMIC } +}; +static const struct column col_compsysproduct[] = +{ + { prop_identifyingnumberW, CIM_STRING|COL_FLAG_KEY }, + { prop_uuidW, CIM_STRING|COL_FLAG_DYNAMIC } +}; +static const struct column col_datafile[] = +{ + { prop_nameW, CIM_STRING|COL_FLAG_DYNAMIC|COL_FLAG_KEY }, + { prop_versionW, CIM_STRING|COL_FLAG_DYNAMIC } +}; +static const struct column col_desktopmonitor[] = +{ + { prop_pixelsperxlogicalinchW, CIM_UINT32 } +}; +static const struct column col_directory[] = +{ + { prop_accessmaskW, CIM_UINT32 }, + { prop_nameW, CIM_STRING|COL_FLAG_DYNAMIC|COL_FLAG_KEY } +}; +static const struct column col_diskdrive[] = +{ + { prop_deviceidW, CIM_STRING|COL_FLAG_DYNAMIC|COL_FLAG_KEY }, + { prop_indexW, CIM_UINT32, VT_I4 }, + { prop_interfacetypeW, CIM_STRING }, + { prop_manufacturerW, CIM_STRING }, + { prop_mediatypeW, CIM_STRING }, + { prop_modelW, CIM_STRING }, + { prop_pnpdeviceidW, CIM_STRING }, + { prop_serialnumberW, CIM_STRING }, + { prop_sizeW, CIM_UINT64 } +}; +static const struct column col_diskpartition[] = +{ + { prop_bootableW, CIM_BOOLEAN }, + { prop_bootpartitionW, CIM_BOOLEAN }, + { prop_deviceidW, CIM_STRING|COL_FLAG_DYNAMIC|COL_FLAG_KEY }, + { prop_diskindexW, CIM_UINT32, VT_I4 }, + { prop_indexW, CIM_UINT32, VT_I4 }, + { prop_pnpdeviceidW, CIM_STRING|COL_FLAG_DYNAMIC }, + { prop_sizeW, CIM_UINT64 }, + { prop_startingoffsetW, CIM_UINT64 }, + { prop_typeW, CIM_STRING|COL_FLAG_DYNAMIC } +}; +static const struct column col_logicaldisk[] = +{ + { prop_deviceidW, CIM_STRING|COL_FLAG_DYNAMIC|COL_FLAG_KEY }, + { prop_drivetypeW, CIM_UINT32, VT_I4 }, + { prop_filesystemW, CIM_STRING|COL_FLAG_DYNAMIC }, + { prop_freespaceW, CIM_UINT64 }, + { prop_nameW, CIM_STRING|COL_FLAG_DYNAMIC }, + { prop_sizeW, CIM_UINT64 }, + { prop_volumenameW, CIM_STRING|COL_FLAG_DYNAMIC }, + { prop_volumeserialnumberW, CIM_STRING|COL_FLAG_DYNAMIC } +}; +static const struct column col_networkadapter[] = +{ + { prop_adaptertypeW, CIM_STRING }, + { prop_deviceidW, CIM_STRING|COL_FLAG_DYNAMIC|COL_FLAG_KEY }, + { prop_indexW, CIM_UINT32, VT_I4 }, + { prop_interfaceindexW, CIM_UINT32, VT_I4 }, + { prop_macaddressW, CIM_STRING|COL_FLAG_DYNAMIC }, + { prop_manufacturerW, CIM_STRING }, + { prop_nameW, CIM_STRING|COL_FLAG_DYNAMIC }, + { prop_netconnectionstatusW, CIM_UINT16, VT_I4 }, + { prop_physicaladapterW, CIM_BOOLEAN }, + { prop_pnpdeviceidW, CIM_STRING }, + { prop_speedW, CIM_UINT64 } +}; +static const struct column col_networkadapterconfig[] = +{ + { prop_defaultipgatewayW, CIM_STRING|CIM_FLAG_ARRAY|COL_FLAG_DYNAMIC }, + { prop_descriptionW, CIM_STRING|COL_FLAG_DYNAMIC }, + { prop_dhcpenabledW, CIM_BOOLEAN }, + { prop_dnshostnameW, CIM_STRING|COL_FLAG_DYNAMIC }, + { prop_dnsserversearchorderW, CIM_STRING|CIM_FLAG_ARRAY|COL_FLAG_DYNAMIC }, + { prop_indexW, CIM_UINT32|COL_FLAG_KEY, VT_I4 }, + { prop_ipconnectionmetricW, CIM_UINT32, VT_I4 }, + { prop_ipenabledW, CIM_BOOLEAN }, + { prop_macaddressW, CIM_STRING|COL_FLAG_DYNAMIC }, + { prop_settingidW, CIM_STRING|COL_FLAG_DYNAMIC } +}; +static const struct column col_os[] = +{ + { prop_buildnumberW, CIM_STRING|COL_FLAG_DYNAMIC }, + { prop_captionW, CIM_STRING|COL_FLAG_DYNAMIC }, + { prop_codesetW, CIM_STRING|COL_FLAG_DYNAMIC }, + { prop_countrycodeW, CIM_STRING|COL_FLAG_DYNAMIC }, + { prop_csdversionW, CIM_STRING|COL_FLAG_DYNAMIC }, + { prop_installdateW, CIM_DATETIME }, + { prop_lastbootuptimeW, CIM_DATETIME|COL_FLAG_DYNAMIC }, + { prop_localdatetimeW, CIM_DATETIME|COL_FLAG_DYNAMIC }, + { prop_localeW, CIM_STRING|COL_FLAG_DYNAMIC }, + { prop_nameW, CIM_STRING|COL_FLAG_DYNAMIC }, + { prop_osarchitectureW, CIM_STRING }, + { prop_oslanguageW, CIM_UINT32, VT_I4 }, + { prop_osproductsuiteW, CIM_UINT32, VT_I4 }, + { prop_ostypeW, CIM_UINT16, VT_I4 }, + { prop_primaryW, CIM_BOOLEAN }, + { prop_serialnumberW, CIM_STRING }, + { prop_servicepackmajorW, CIM_UINT16, VT_I4 }, + { prop_servicepackminorW, CIM_UINT16, VT_I4 }, + { prop_suitemaskW, CIM_UINT32, VT_I4 }, + { prop_systemdirectoryW, CIM_STRING|COL_FLAG_DYNAMIC }, + { prop_totalvisiblememorysizeW, CIM_UINT64 }, + { prop_versionW, CIM_STRING|COL_FLAG_DYNAMIC } +}; +static const struct column col_param[] = +{ + { prop_classW, CIM_STRING }, + { prop_methodW, CIM_STRING }, + { prop_directionW, CIM_SINT32 }, + { prop_parameterW, CIM_STRING }, + { prop_typeW, CIM_UINT32 }, + { prop_varianttypeW, CIM_UINT32 }, + { prop_defaultvalueW, CIM_UINT32 } +}; +static const struct column col_physicalmedia[] = +{ + { prop_serialnumberW, CIM_STRING }, + { prop_tagW, CIM_STRING } +}; +static const struct column col_physicalmemory[] = +{ + { prop_capacityW, CIM_UINT64 } +}; +static const struct column col_printer[] = +{ + { prop_attributesW, CIM_UINT32 }, + { prop_drivernameW, CIM_STRING|COL_FLAG_DYNAMIC }, + { prop_horizontalresolutionW, CIM_UINT32 }, + { prop_localW, CIM_BOOLEAN }, + { prop_nameW, CIM_STRING|COL_FLAG_DYNAMIC }, + { prop_networkW, CIM_BOOLEAN }, + { prop_deviceidW, CIM_STRING|COL_FLAG_DYNAMIC|COL_FLAG_KEY }, + { prop_portnameW, CIM_STRING|COL_FLAG_DYNAMIC }, + { prop_locationW, CIM_STRING|COL_FLAG_DYNAMIC }, +}; +static const struct column col_process[] = +{ + { prop_captionW, CIM_STRING|COL_FLAG_DYNAMIC }, + { prop_commandlineW, CIM_STRING|COL_FLAG_DYNAMIC }, + { prop_descriptionW, CIM_STRING|COL_FLAG_DYNAMIC }, + { prop_handleW, CIM_STRING|COL_FLAG_DYNAMIC|COL_FLAG_KEY }, + { prop_nameW, CIM_STRING|COL_FLAG_DYNAMIC }, + { prop_pprocessidW, CIM_UINT32, VT_I4 }, + { prop_processidW, CIM_UINT32, VT_I4 }, + { prop_threadcountW, CIM_UINT32, VT_I4 }, + { prop_workingsetsizeW, CIM_UINT64 }, + /* methods */ + { method_getownerW, CIM_FLAG_ARRAY|COL_FLAG_METHOD } +}; +static const struct column col_processor[] = +{ + { prop_addresswidthW, CIM_UINT16, VT_I4 }, + { prop_captionW, CIM_STRING|COL_FLAG_DYNAMIC }, + { prop_cpustatusW, CIM_UINT16 }, + { prop_currentclockspeedW, CIM_UINT32, VT_I4 }, + { prop_datawidthW, CIM_UINT16, VT_I4 }, + { prop_descriptionW, CIM_STRING|COL_FLAG_DYNAMIC }, + { prop_deviceidW, CIM_STRING|COL_FLAG_DYNAMIC|COL_FLAG_KEY }, + { prop_familyW, CIM_UINT16, VT_I4 }, + { prop_manufacturerW, CIM_STRING|COL_FLAG_DYNAMIC }, + { prop_maxclockspeedW, CIM_UINT32, VT_I4 }, + { prop_nameW, CIM_STRING|COL_FLAG_DYNAMIC }, + { prop_numcoresW, CIM_UINT32, VT_I4 }, + { prop_numlogicalprocessorsW, CIM_UINT32, VT_I4 }, + { prop_processoridW, CIM_STRING|COL_FLAG_DYNAMIC }, + { prop_processortypeW, CIM_UINT16, VT_I4 }, + { prop_uniqueidW, CIM_STRING }, + { prop_versionW, CIM_STRING|COL_FLAG_DYNAMIC } +}; +static const struct column col_qualifier[] = +{ + { prop_classW, CIM_STRING }, + { prop_memberW, CIM_STRING }, + { prop_typeW, CIM_UINT32 }, + { prop_flavorW, CIM_SINT32 }, + { prop_nameW, CIM_STRING }, + { prop_intvalueW, CIM_SINT32 }, + { prop_strvalueW, CIM_STRING } +}; +static const struct column col_service[] = +{ + { prop_acceptpauseW, CIM_BOOLEAN }, + { prop_acceptstopW, CIM_BOOLEAN }, + { prop_displaynameW, CIM_STRING|COL_FLAG_DYNAMIC }, + { prop_nameW, CIM_STRING|COL_FLAG_DYNAMIC|COL_FLAG_KEY }, + { prop_processidW, CIM_UINT32 }, + { prop_servicetypeW, CIM_STRING }, + { prop_startmodeW, CIM_STRING }, + { prop_stateW, CIM_STRING }, + { prop_systemnameW, CIM_STRING|COL_FLAG_DYNAMIC }, + /* methods */ + { method_pauseserviceW, CIM_FLAG_ARRAY|COL_FLAG_METHOD }, + { method_resumeserviceW, CIM_FLAG_ARRAY|COL_FLAG_METHOD }, + { method_startserviceW, CIM_FLAG_ARRAY|COL_FLAG_METHOD }, + { method_stopserviceW, CIM_FLAG_ARRAY|COL_FLAG_METHOD } +}; +static const struct column col_sid[] = +{ + { prop_accountnameW, CIM_STRING|COL_FLAG_DYNAMIC }, + { prop_binaryrepresentationW, CIM_UINT8|CIM_FLAG_ARRAY|COL_FLAG_DYNAMIC }, + { prop_referenceddomainnameW, CIM_STRING|COL_FLAG_DYNAMIC }, + { prop_sidW, CIM_STRING|COL_FLAG_DYNAMIC|COL_FLAG_KEY }, + { prop_sidlengthW, CIM_UINT32 } +}; +static const struct column col_sounddevice[] = +{ + { prop_nameW, CIM_STRING }, + { prop_productnameW, CIM_STRING }, + { prop_statusinfoW, CIM_UINT16, VT_I4 } +}; +static const struct column col_stdregprov[] = +{ + { method_enumkeyW, CIM_FLAG_ARRAY|COL_FLAG_METHOD }, + { method_enumvaluesW, CIM_FLAG_ARRAY|COL_FLAG_METHOD }, + { method_getstringvalueW, CIM_FLAG_ARRAY|COL_FLAG_METHOD } +}; +static const struct column col_systemenclosure[] = +{ + { prop_captionW, CIM_STRING }, + { prop_chassistypesW, CIM_UINT16|CIM_FLAG_ARRAY, VT_I4|VT_ARRAY }, + { prop_descriptionW, CIM_STRING }, + { prop_lockpresentW, CIM_BOOLEAN }, + { prop_manufacturerW, CIM_STRING }, + { prop_nameW, CIM_STRING }, + { prop_tagW, CIM_STRING }, +}; +static const struct column col_systemsecurity[] = +{ + { method_getsdW, CIM_FLAG_ARRAY|COL_FLAG_METHOD }, + { method_setsdW, CIM_FLAG_ARRAY|COL_FLAG_METHOD }, +}; +static const struct column col_videocontroller[] = +{ + { prop_adapterdactypeW, CIM_STRING }, + { prop_adapterramW, CIM_UINT32, VT_I4 }, + { prop_availabilityW, CIM_UINT16 }, + { prop_captionW, CIM_STRING|COL_FLAG_DYNAMIC }, + { prop_currentbitsperpixelW, CIM_UINT32, VT_I4 }, + { prop_currenthorizontalresW, CIM_UINT32, VT_I4 }, + { prop_currentrefreshrateW, CIM_UINT32, VT_I4 }, + { prop_currentscanmodeW, CIM_UINT16, VT_I4 }, + { prop_currentverticalresW, CIM_UINT32, VT_I4 }, + { prop_descriptionW, CIM_STRING|COL_FLAG_DYNAMIC }, + { prop_deviceidW, CIM_STRING|COL_FLAG_KEY }, + { prop_driverversionW, CIM_STRING }, + { prop_nameW, CIM_STRING|COL_FLAG_DYNAMIC }, + { prop_pnpdeviceidW, CIM_STRING|COL_FLAG_DYNAMIC }, + { prop_videoarchitectureW, CIM_UINT16, VT_I4 }, + { prop_videomemorytypeW, CIM_UINT16, VT_I4 }, + { prop_videomodedescriptionW, CIM_STRING|COL_FLAG_DYNAMIC }, + { prop_videoprocessorW, CIM_STRING|COL_FLAG_DYNAMIC } +}; + +static const WCHAR baseboard_manufacturerW[] = + {'I','n','t','e','l',' ','C','o','r','p','o','r','a','t','i','o','n',0}; +static const WCHAR baseboard_serialnumberW[] = + {'N','o','n','e',0}; +static const WCHAR baseboard_tagW[] = + {'B','a','s','e',' ','B','o','a','r','d',0}; +static const WCHAR baseboard_versionW[] = + {'1','.','0',0}; +static const WCHAR bios_descriptionW[] = + {'D','e','f','a','u','l','t',' ','S','y','s','t','e','m',' ','B','I','O','S',0}; +static const WCHAR bios_manufacturerW[] = + {'T','h','e',' ','W','i','n','e',' ','P','r','o','j','e','c','t',0}; +static const WCHAR bios_nameW[] = + {'W','I','N','E',' ','B','I','O','S',0}; +static const WCHAR bios_releasedateW[] = + {'2','0','1','2','0','6','0','8','0','0','0','0','0','0','.','0','0','0','0','0','0','+','0','0','0',0}; +static const WCHAR bios_serialnumberW[] = + {'0',0}; +static const WCHAR bios_smbiosbiosversionW[] = + {'W','i','n','e',0}; +static const WCHAR bios_versionW[] = + {'W','I','N','E',' ',' ',' ','-',' ','1',0}; +static const WCHAR cdromdrive_mediatypeW[] = + {'C','D','-','R','O','M',0}; +static const WCHAR cdromdrive_nameW[] = + {'W','i','n','e',' ','C','D','-','R','O','M',' ','A','T','A',' ','D','e','v','i','c','e',0}; +static const WCHAR cdromdrive_pnpdeviceidW[]= + {'I','D','E','\\','C','D','R','O','M','W','I','N','E','_','C','D','-','R','O','M', + '_','_','_','_','_','_','_','_','_','_','_','_','_','_','_','_','_','_','_','_','_','_', + '_','_','_','_','_','_','_','1','.','0','_','_','_','_','_','\\','5','&','3','A','2', + 'A','5','8','5','4','&','0','&','1','.','0','.','0',0}; +static const WCHAR compsys_descriptionW[] = + {'A','T','/','A','T',' ','C','O','M','P','A','T','I','B','L','E',0}; +static const WCHAR compsys_domainW[] = + {'W','O','R','K','G','R','O','U','P',0}; +static const WCHAR compsys_manufacturerW[] = + {'T','h','e',' ','W','i','n','e',' ','P','r','o','j','e','c','t',0}; +static const WCHAR compsys_modelW[] = + {'W','i','n','e',0}; +static const WCHAR compsysproduct_identifyingnumberW[] = + {'0',0}; +static const WCHAR compsysproduct_uuidW[] = + {'0','0','0','0','0','0','0','0','-','0','0','0','0','-','0','0','0','0','-','0','0','0','0','-', + '0','0','0','0','0','0','0','0','0','0','0','0',0}; +static const WCHAR diskdrive_interfacetypeW[] = + {'I','D','E',0}; +static const WCHAR diskdrive_manufacturerW[] = + {'(','S','t','a','n','d','a','r','d',' ','d','i','s','k',' ','d','r','i','v','e','s',')',0}; +static const WCHAR diskdrive_mediatype_fixedW[] = + {'F','i','x','e','d',' ','h','a','r','d',' ','d','i','s','k',0}; +static const WCHAR diskdrive_mediatype_removableW[] = + {'R','e','m','o','v','a','b','l','e',' ','m','e','d','i','a',0}; +static const WCHAR diskdrive_modelW[] = + {'W','i','n','e',' ','D','i','s','k',' ','D','r','i','v','e',0}; +static const WCHAR diskdrive_pnpdeviceidW[] = + {'I','D','E','\\','D','i','s','k','\\','V','E','N','_','W','I','N','E',0}; +static const WCHAR diskdrive_serialW[] = + {'W','I','N','E','H','D','I','S','K',0}; +static const WCHAR networkadapter_pnpdeviceidW[]= + {'P','C','I','\\','V','E','N','_','8','0','8','6','&','D','E','V','_','1','0','0','E','&', + 'S','U','B','S','Y','S','_','0','0','1','E','8','0','8','6','&','R','E','V','_','0','2','\\', + '3','&','2','6','7','A','6','1','6','A','&','1','&','1','8',0}; +static const WCHAR os_32bitW[] = + {'3','2','-','b','i','t',0}; +static const WCHAR os_64bitW[] = + {'6','4','-','b','i','t',0}; +static const WCHAR os_installdateW[] = + {'2','0','1','4','0','1','0','1','0','0','0','0','0','0','.','0','0','0','0','0','0','+','0','0','0',0}; +static const WCHAR os_serialnumberW[] = + {'1','2','3','4','5','-','O','E','M','-','1','2','3','4','5','6','7','-','1','2','3','4','5',0}; +static const WCHAR physicalmedia_tagW[] = + {'\\','\\','.','\\','P','H','Y','S','I','C','A','L','D','R','I','V','E','0',0}; +static const WCHAR sounddevice_productnameW[] = + {'W','i','n','e',' ','A','u','d','i','o',' ','D','e','v','i','c','e',0}; +static const WCHAR systemenclosure_systemenclosureW[] = + {'S','y','s','t','e','m',' ','E','n','c','l','o','s','u','r','e',0}; +static const WCHAR systemenclosure_tagW[] = + {'S','y','s','t','e','m',' ','E','n','c','l','o','s','u','r','e',' ','0',0}; +static const WCHAR systemenclosure_manufacturerW[] = + {'W','i','n','e',0}; +static const WCHAR videocontroller_dactypeW[] = + {'I','n','t','e','g','r','a','t','e','d',' ','R','A','M','D','A','C',0}; +static const WCHAR videocontroller_deviceidW[] = + {'V','i','d','e','o','C','o','n','t','r','o','l','l','e','r','1',0}; +static const WCHAR videocontroller_driverversionW[] = + {'1','.','0',0}; + +#include "pshpack1.h" +struct record_baseboard +{ + const WCHAR *manufacturer; + const WCHAR *model; + const WCHAR *name; + const WCHAR *product; + const WCHAR *serialnumber; + const WCHAR *tag; + const WCHAR *version; +}; +struct record_bios +{ + const WCHAR *description; + const WCHAR *identificationcode; + const WCHAR *manufacturer; + const WCHAR *name; + const WCHAR *releasedate; + const WCHAR *serialnumber; + const WCHAR *smbiosbiosversion; + const WCHAR *version; +}; +struct record_cdromdrive +{ + const WCHAR *device_id; + const WCHAR *drive; + const WCHAR *mediatype; + const WCHAR *name; + const WCHAR *pnpdevice_id; +}; +struct record_computersystem +{ + const WCHAR *description; + const WCHAR *domain; + UINT16 domainrole; + const WCHAR *manufacturer; + const WCHAR *model; + const WCHAR *name; + UINT32 num_logical_processors; + UINT32 num_processors; + UINT64 total_physical_memory; + const WCHAR *username; +}; +struct record_computersystemproduct +{ + const WCHAR *identifyingnumber; + const WCHAR *uuid; +}; +struct record_datafile +{ + const WCHAR *name; + const WCHAR *version; +}; +struct record_desktopmonitor +{ + UINT32 pixelsperxlogicalinch; +}; +struct record_directory +{ + UINT32 accessmask; + const WCHAR *name; +}; +struct record_diskdrive +{ + const WCHAR *device_id; + UINT32 index; + const WCHAR *interfacetype; + const WCHAR *manufacturer; + const WCHAR *mediatype; + const WCHAR *model; + const WCHAR *pnpdevice_id; + const WCHAR *serialnumber; + UINT64 size; +}; +struct record_diskpartition +{ + int bootable; + int bootpartition; + const WCHAR *device_id; + UINT32 diskindex; + UINT32 index; + const WCHAR *pnpdevice_id; + UINT64 size; + UINT64 startingoffset; + const WCHAR *type; +}; +struct record_logicaldisk +{ + const WCHAR *device_id; + UINT32 drivetype; + const WCHAR *filesystem; + UINT64 freespace; + const WCHAR *name; + UINT64 size; + const WCHAR *volumename; + const WCHAR *volumeserialnumber; +}; +struct record_networkadapter +{ + const WCHAR *adaptertype; + const WCHAR *device_id; + UINT32 index; + UINT32 interface_index; + const WCHAR *mac_address; + const WCHAR *manufacturer; + const WCHAR *name; + UINT16 netconnection_status; + int physicaladapter; + const WCHAR *pnpdevice_id; + UINT64 speed; +}; +struct record_networkadapterconfig +{ + const struct array *defaultipgateway; + const WCHAR *description; + int dhcpenabled; + const WCHAR *dnshostname; + const struct array *dnsserversearchorder; + UINT32 index; + UINT32 ipconnectionmetric; + int ipenabled; + const WCHAR *mac_address; + const WCHAR *settingid; +}; +struct record_operatingsystem +{ + const WCHAR *buildnumber; + const WCHAR *caption; + const WCHAR *codeset; + const WCHAR *countrycode; + const WCHAR *csdversion; + const WCHAR *installdate; + const WCHAR *lastbootuptime; + const WCHAR *localdatetime; + const WCHAR *locale; + const WCHAR *name; + const WCHAR *osarchitecture; + UINT32 oslanguage; + UINT32 osproductsuite; + UINT16 ostype; + int primary; + const WCHAR *serialnumber; + UINT16 servicepackmajor; + UINT16 servicepackminor; + UINT32 suitemask; + const WCHAR *systemdirectory; + UINT64 totalvisiblememorysize; + const WCHAR *version; +}; +struct record_param +{ + const WCHAR *class; + const WCHAR *method; + INT32 direction; + const WCHAR *parameter; + UINT32 type; + UINT32 varianttype; + UINT32 defaultvalue; +}; +struct record_physicalmedia +{ + const WCHAR *serialnumber; + const WCHAR *tag; +}; +struct record_physicalmemory +{ + UINT64 capacity; +}; +struct record_printer +{ + UINT32 attributes; + const WCHAR *drivername; + UINT32 horizontalresolution; + int local; + const WCHAR *name; + int network; + const WCHAR *device_id; + const WCHAR *portname; + const WCHAR *location; +}; +struct record_process +{ + const WCHAR *caption; + const WCHAR *commandline; + const WCHAR *description; + const WCHAR *handle; + const WCHAR *name; + UINT32 pprocess_id; + UINT32 process_id; + UINT32 thread_count; + UINT64 workingsetsize; + /* methods */ + class_method *get_owner; +}; +struct record_processor +{ + UINT16 addresswidth; + const WCHAR *caption; + UINT16 cpu_status; + UINT32 currentclockspeed; + UINT16 datawidth; + const WCHAR *description; + const WCHAR *device_id; + UINT16 family; + const WCHAR *manufacturer; + UINT32 maxclockspeed; + const WCHAR *name; + UINT32 num_cores; + UINT32 num_logical_processors; + const WCHAR *processor_id; + UINT16 processortype; + const WCHAR *unique_id; + const WCHAR *version; +}; +struct record_qualifier +{ + const WCHAR *class; + const WCHAR *member; + UINT32 type; + INT32 flavor; + const WCHAR *name; + INT32 intvalue; + const WCHAR *strvalue; +}; +struct record_service +{ + int accept_pause; + int accept_stop; + const WCHAR *displayname; + const WCHAR *name; + UINT32 process_id; + const WCHAR *servicetype; + const WCHAR *startmode; + const WCHAR *state; + const WCHAR *systemname; + /* methods */ + class_method *pause_service; + class_method *resume_service; + class_method *start_service; + class_method *stop_service; +}; +struct record_sid +{ + const WCHAR *accountname; + const struct array *binaryrepresentation; + const WCHAR *referenceddomainname; + const WCHAR *sid; + UINT32 sidlength; +}; +struct record_sounddevice +{ + const WCHAR *name; + const WCHAR *productname; + UINT16 statusinfo; +}; +struct record_stdregprov +{ + class_method *enumkey; + class_method *enumvalues; + class_method *getstringvalue; +}; +struct record_systemsecurity +{ + class_method *getsd; + class_method *setsd; +}; +struct record_systemenclosure +{ + const WCHAR *caption; + const struct array *chassistypes; + const WCHAR *description; + int lockpresent; + const WCHAR *manufacturer; + const WCHAR *name; + const WCHAR *tag; +}; +struct record_videocontroller +{ + const WCHAR *adapter_dactype; + UINT32 adapter_ram; + UINT16 availability; + const WCHAR *caption; + UINT32 current_bitsperpixel; + UINT32 current_horizontalres; + UINT32 current_refreshrate; + UINT16 current_scanmode; + UINT32 current_verticalres; + const WCHAR *description; + const WCHAR *device_id; + const WCHAR *driverversion; + const WCHAR *name; + const WCHAR *pnpdevice_id; + UINT16 videoarchitecture; + UINT16 videomemorytype; + const WCHAR *videomodedescription; + const WCHAR *videoprocessor; +}; +#include "poppack.h" + +static const struct record_baseboard data_baseboard[] = +{ + { baseboard_manufacturerW, baseboard_tagW, baseboard_tagW, baseboard_tagW, baseboard_serialnumberW, baseboard_versionW } +}; +static const struct record_bios data_bios[] = +{ + { bios_descriptionW, NULL, bios_manufacturerW, bios_nameW, bios_releasedateW, bios_serialnumberW, + bios_smbiosbiosversionW, bios_versionW } +}; +static const struct record_param data_param[] = +{ + { class_processW, method_getownerW, -1, param_returnvalueW, CIM_UINT32, VT_I4 }, + { class_processW, method_getownerW, -1, param_userW, CIM_STRING }, + { class_processW, method_getownerW, -1, param_domainW, CIM_STRING }, + { class_serviceW, method_pauseserviceW, -1, param_returnvalueW, CIM_UINT32, VT_I4 }, + { class_serviceW, method_resumeserviceW, -1, param_returnvalueW, CIM_UINT32, VT_I4 }, + { class_serviceW, method_startserviceW, -1, param_returnvalueW, CIM_UINT32, VT_I4 }, + { class_serviceW, method_stopserviceW, -1, param_returnvalueW, CIM_UINT32, VT_I4 }, + { class_stdregprovW, method_enumkeyW, 1, param_defkeyW, CIM_SINT32, 0, 0x80000002 }, + { class_stdregprovW, method_enumkeyW, 1, param_subkeynameW, CIM_STRING }, + { class_stdregprovW, method_enumkeyW, -1, param_returnvalueW, CIM_UINT32, VT_I4 }, + { class_stdregprovW, method_enumkeyW, -1, param_namesW, CIM_STRING|CIM_FLAG_ARRAY }, + { class_stdregprovW, method_enumvaluesW, 1, param_defkeyW, CIM_SINT32, 0, 0x80000002 }, + { class_stdregprovW, method_enumvaluesW, 1, param_subkeynameW, CIM_STRING }, + { class_stdregprovW, method_enumvaluesW, -1, param_returnvalueW, CIM_UINT32, VT_I4 }, + { class_stdregprovW, method_enumvaluesW, -1, param_namesW, CIM_STRING|CIM_FLAG_ARRAY }, + { class_stdregprovW, method_enumvaluesW, -1, param_typesW, CIM_SINT32|CIM_FLAG_ARRAY }, + { class_stdregprovW, method_getstringvalueW, 1, param_defkeyW, CIM_SINT32, 0, 0x80000002 }, + { class_stdregprovW, method_getstringvalueW, 1, param_subkeynameW, CIM_STRING }, + { class_stdregprovW, method_getstringvalueW, 1, param_valuenameW, CIM_STRING }, + { class_stdregprovW, method_getstringvalueW, -1, param_returnvalueW, CIM_UINT32, VT_I4 }, + { class_stdregprovW, method_getstringvalueW, -1, param_valueW, CIM_STRING }, + { class_systemsecurityW, method_getsdW, -1, param_returnvalueW, CIM_UINT32, VT_I4 }, + { class_systemsecurityW, method_getsdW, -1, param_sdW, CIM_UINT8|CIM_FLAG_ARRAY }, + { class_systemsecurityW, method_setsdW, 1, param_sdW, CIM_UINT8|CIM_FLAG_ARRAY }, + { class_systemsecurityW, method_setsdW, -1, param_returnvalueW, CIM_UINT32, VT_I4 }, +}; + +#define FLAVOR_ID (WBEM_FLAVOR_FLAG_PROPAGATE_TO_INSTANCE | WBEM_FLAVOR_NOT_OVERRIDABLE |\ + WBEM_FLAVOR_ORIGIN_PROPAGATED) + +static const struct record_physicalmedia data_physicalmedia[] = +{ + { diskdrive_serialW, physicalmedia_tagW } +}; +static const struct record_qualifier data_qualifier[] = +{ + { class_process_getowner_outW, param_userW, CIM_SINT32, FLAVOR_ID, prop_idW, 0 }, + { class_process_getowner_outW, param_domainW, CIM_SINT32, FLAVOR_ID, prop_idW, 1 } +}; +static const struct record_sounddevice data_sounddevice[] = +{ + { sounddevice_productnameW, sounddevice_productnameW, 3 /* enabled */ } +}; +static const struct record_stdregprov data_stdregprov[] = +{ + { reg_enum_key, reg_enum_values, reg_get_stringvalue } +}; +static UINT16 systemenclosure_chassistypes[] = +{ + 1, +}; +static const struct array systemenclosure_chassistypes_array = +{ + SIZEOF(systemenclosure_chassistypes), + &systemenclosure_chassistypes +}; +static const struct record_systemenclosure data_systemenclosure[] = +{ + { + systemenclosure_systemenclosureW, + &systemenclosure_chassistypes_array, + systemenclosure_systemenclosureW, + FALSE, + systemenclosure_manufacturerW, + systemenclosure_systemenclosureW, + systemenclosure_tagW, + } +}; +static const struct record_systemsecurity data_systemsecurity[] = +{ + { security_get_sd, security_set_sd } +}; + +/* check if row matches condition and update status */ +static BOOL match_row( const struct table *table, UINT row, const struct expr *cond, enum fill_status *status ) +{ + LONGLONG val; + UINT type; + + if (!cond) + { + *status = FILL_STATUS_UNFILTERED; + return TRUE; + } + if (eval_cond( table, row, cond, &val, &type ) != S_OK) + { + *status = FILL_STATUS_FAILED; + return FALSE; + } + *status = FILL_STATUS_FILTERED; + return val != 0; +} + +static BOOL resize_table( struct table *table, UINT row_count, UINT row_size ) +{ + if (!table->num_rows_allocated) + { + if (!(table->data = heap_alloc( row_count * row_size ))) return FALSE; + table->num_rows_allocated = row_count; + return TRUE; + } + if (row_count > table->num_rows_allocated) + { + BYTE *data; + UINT count = max( row_count, table->num_rows_allocated * 2 ); + if (!(data = heap_realloc( table->data, count * row_size ))) return FALSE; + table->data = data; + table->num_rows_allocated = count; + } + return TRUE; +} + +static enum fill_status fill_cdromdrive( struct table *table, const struct expr *cond ) +{ + static const WCHAR fmtW[] = {'%','c',':',0}; + WCHAR drive[3], root[] = {'A',':','\\',0}; + struct record_cdromdrive *rec; + UINT i, row = 0, offset = 0; + DWORD drives = GetLogicalDrives(); + enum fill_status status = FILL_STATUS_UNFILTERED; + + if (!resize_table( table, 1, sizeof(*rec) )) return FILL_STATUS_FAILED; + + for (i = 0; i < 26; i++) + { + if (drives & (1 << i)) + { + root[0] = 'A' + i; + if (GetDriveTypeW( root ) != DRIVE_CDROM) + continue; + + if (!resize_table( table, row + 1, sizeof(*rec) )) return FILL_STATUS_FAILED; + + rec = (struct record_cdromdrive *)(table->data + offset); + rec->device_id = cdromdrive_pnpdeviceidW; + sprintfW( drive, fmtW, 'A' + i ); + rec->drive = heap_strdupW( drive ); + rec->mediatype = cdromdrive_mediatypeW; + rec->name = cdromdrive_nameW; + rec->pnpdevice_id = cdromdrive_pnpdeviceidW; + if (!match_row( table, row, cond, &status )) + { + free_row_values( table, row ); + continue; + } + offset += sizeof(*rec); + row++; + } + } + TRACE("created %u rows\n", row); + table->num_rows = row; + return status; +} + +static UINT get_processor_count(void) +{ + SYSTEM_BASIC_INFORMATION info; + + if (NtQuerySystemInformation( SystemBasicInformation, &info, sizeof(info), NULL )) return 1; + return info.NumberOfProcessors; +} + +static UINT get_logical_processor_count( UINT *num_cores ) +{ + SYSTEM_LOGICAL_PROCESSOR_INFORMATION *info; + UINT i, j, count = 0; + NTSTATUS status; + ULONG len; + + if (num_cores) *num_cores = get_processor_count(); + status = NtQuerySystemInformation( SystemLogicalProcessorInformation, NULL, 0, &len ); + if (status != STATUS_INFO_LENGTH_MISMATCH) return get_processor_count(); + + if (!(info = heap_alloc( len ))) return get_processor_count(); + status = NtQuerySystemInformation( SystemLogicalProcessorInformation, info, len, &len ); + if (status != STATUS_SUCCESS) + { + heap_free( info ); + return get_processor_count(); + } + if (num_cores) *num_cores = 0; + for (i = 0; i < len / sizeof(*info); i++) + { + if (info[i].Relationship == RelationProcessorCore) + { + for (j = 0; j < sizeof(ULONG_PTR); j++) if (info[i].ProcessorMask & (1 << j)) count++; + } + else if (info[i].Relationship == RelationProcessorPackage && num_cores) + { + for (j = 0; j < sizeof(ULONG_PTR); j++) if (info[i].ProcessorMask & (1 << j)) (*num_cores)++; + } + } + heap_free( info ); + return count; +} + +static UINT64 get_total_physical_memory(void) +{ + MEMORYSTATUSEX status; + + status.dwLength = sizeof(status); + if (!GlobalMemoryStatusEx( &status )) return 1024 * 1024 * 1024; + return status.ullTotalPhys; +} + +static WCHAR *get_computername(void) +{ + WCHAR *ret; + DWORD size = MAX_COMPUTERNAME_LENGTH + 1; + + if (!(ret = heap_alloc( size * sizeof(WCHAR) ))) return NULL; + GetComputerNameW( ret, &size ); + return ret; +} + +static WCHAR *get_username(void) +{ + WCHAR *ret; + DWORD compsize, usersize; + DWORD size; + + compsize = 0; + GetComputerNameW( NULL, &compsize ); + usersize = 0; + GetUserNameW( NULL, &usersize ); + size = compsize + usersize; /* two null terminators account for the \ */ + if (!(ret = heap_alloc( size * sizeof(WCHAR) ))) return NULL; + GetComputerNameW( ret, &compsize ); + ret[compsize] = '\\'; + GetUserNameW( ret + compsize + 1, &usersize ); + return ret; +} + +static enum fill_status fill_compsys( struct table *table, const struct expr *cond ) +{ + struct record_computersystem *rec; + enum fill_status status = FILL_STATUS_UNFILTERED; + UINT row = 0; + + if (!resize_table( table, 1, sizeof(*rec) )) return FILL_STATUS_FAILED; + + rec = (struct record_computersystem *)table->data; + rec->description = compsys_descriptionW; + rec->domain = compsys_domainW; + rec->domainrole = 0; /* standalone workstation */ + rec->manufacturer = compsys_manufacturerW; + rec->model = compsys_modelW; + rec->name = get_computername(); + rec->num_logical_processors = get_logical_processor_count( NULL ); + rec->num_processors = get_processor_count(); + rec->total_physical_memory = get_total_physical_memory(); + rec->username = get_username(); + if (!match_row( table, row, cond, &status )) free_row_values( table, row ); + else row++; + + TRACE("created %u rows\n", row); + table->num_rows = row; + return status; +} + +static WCHAR *get_compsysproduct_uuid(void) +{ +#ifdef __APPLE__ + unsigned char uuid[16]; + const struct timespec timeout = {1, 0}; + if (!gethostuuid( uuid, &timeout )) + { + static const WCHAR fmtW[] = + {'%','0','2','X','%','0','2','X','%','0','2','X','%','0','2','X','-','%','0','2','X','%','0','2','X','-', + '%','0','2','X','%','0','2','X','-','%','0','2','X','%','0','2','X','-','%','0','2','X','%','0','2','X', + '%','0','2','X','%','0','2','X','%','0','2','X','%','0','2','X',0}; + WCHAR *ret = heap_alloc( 37 * sizeof(WCHAR) ); + if (!ret) return NULL; + sprintfW( ret, fmtW, uuid[0], uuid[1], uuid[2], uuid[3], uuid[4], uuid[5], uuid[6], uuid[7], + uuid[8], uuid[9], uuid[10], uuid[11], uuid[12], uuid[13], uuid[14], uuid[15] ); + return ret; + } +#endif + return heap_strdupW( compsysproduct_uuidW ); +} + +static enum fill_status fill_compsysproduct( struct table *table, const struct expr *cond ) +{ + struct record_computersystemproduct *rec; + enum fill_status status = FILL_STATUS_UNFILTERED; + UINT row = 0; + + if (!resize_table( table, 1, sizeof(*rec) )) return FILL_STATUS_FAILED; + + rec = (struct record_computersystemproduct *)table->data; + rec->identifyingnumber = compsysproduct_identifyingnumberW; + rec->uuid = get_compsysproduct_uuid(); + if (!match_row( table, row, cond, &status )) free_row_values( table, row ); + else row++; + + TRACE("created %u rows\n", row); + table->num_rows = row; + return status; +} + +struct dirstack +{ + WCHAR **dirs; + UINT *len_dirs; + UINT num_dirs; + UINT num_allocated; +}; + +static struct dirstack *alloc_dirstack( UINT size ) +{ + struct dirstack *dirstack; + + if (!(dirstack = heap_alloc( sizeof(*dirstack) ))) return NULL; + if (!(dirstack->dirs = heap_alloc( sizeof(WCHAR *) * size ))) + { + heap_free( dirstack ); + return NULL; + } + if (!(dirstack->len_dirs = heap_alloc( sizeof(UINT) * size ))) + { + heap_free( dirstack->dirs ); + heap_free( dirstack ); + return NULL; + } + dirstack->num_dirs = 0; + dirstack->num_allocated = size; + return dirstack; +} + +static void clear_dirstack( struct dirstack *dirstack ) +{ + UINT i; + for (i = 0; i < dirstack->num_dirs; i++) heap_free( dirstack->dirs[i] ); + dirstack->num_dirs = 0; +} + +static void free_dirstack( struct dirstack *dirstack ) +{ + clear_dirstack( dirstack ); + heap_free( dirstack->dirs ); + heap_free( dirstack->len_dirs ); + heap_free( dirstack ); +} + +static BOOL push_dir( struct dirstack *dirstack, WCHAR *dir, UINT len ) +{ + UINT size, i = dirstack->num_dirs; + + if (!dir) return FALSE; + + if (i == dirstack->num_allocated) + { + WCHAR **tmp; + UINT *len_tmp; + + size = dirstack->num_allocated * 2; + if (!(tmp = heap_realloc( dirstack->dirs, size * sizeof(WCHAR *) ))) return FALSE; + dirstack->dirs = tmp; + if (!(len_tmp = heap_realloc( dirstack->len_dirs, size * sizeof(UINT) ))) return FALSE; + dirstack->len_dirs = len_tmp; + dirstack->num_allocated = size; + } + dirstack->dirs[i] = dir; + dirstack->len_dirs[i] = len; + dirstack->num_dirs++; + return TRUE; +} + +static WCHAR *pop_dir( struct dirstack *dirstack, UINT *len ) +{ + if (!dirstack->num_dirs) + { + *len = 0; + return NULL; + } + dirstack->num_dirs--; + *len = dirstack->len_dirs[dirstack->num_dirs]; + return dirstack->dirs[dirstack->num_dirs]; +} + +static const WCHAR *peek_dir( struct dirstack *dirstack ) +{ + if (!dirstack->num_dirs) return NULL; + return dirstack->dirs[dirstack->num_dirs - 1]; +} + +static WCHAR *build_glob( WCHAR drive, const WCHAR *path, UINT len ) +{ + UINT i = 0; + WCHAR *ret; + + if (!(ret = heap_alloc( (len + 6) * sizeof(WCHAR) ))) return NULL; + ret[i++] = drive; + ret[i++] = ':'; + ret[i++] = '\\'; + if (path && len) + { + memcpy( ret + i, path, len * sizeof(WCHAR) ); + i += len; + ret[i++] = '\\'; + } + ret[i++] = '*'; + ret[i] = 0; + return ret; +} + +static WCHAR *build_name( WCHAR drive, const WCHAR *path ) +{ + UINT i = 0, len = 0; + const WCHAR *p; + WCHAR *ret; + + for (p = path; *p; p++) + { + if (*p == '\\') len += 2; + else len++; + }; + if (!(ret = heap_alloc( (len + 5) * sizeof(WCHAR) ))) return NULL; + ret[i++] = drive; + ret[i++] = ':'; + ret[i++] = '\\'; + ret[i++] = '\\'; + for (p = path; *p; p++) + { + if (*p != '\\') ret[i++] = *p; + else + { + ret[i++] = '\\'; + ret[i++] = '\\'; + } + } + ret[i] = 0; + return ret; +} + +static WCHAR *build_dirname( const WCHAR *path, UINT *ret_len ) +{ + const WCHAR *p = path, *start; + UINT len, i; + WCHAR *ret; + + if (!isalphaW( p[0] ) || p[1] != ':' || p[2] != '\\' || p[3] != '\\' || !p[4]) return NULL; + start = path + 4; + len = strlenW( start ); + p = start + len - 1; + if (*p == '\\') return NULL; + + while (p >= start && *p != '\\') { len--; p--; }; + while (p >= start && *p == '\\') { len--; p--; }; + + if (!(ret = heap_alloc( (len + 1) * sizeof(WCHAR) ))) return NULL; + for (i = 0, p = start; p < start + len; p++) + { + if (p[0] == '\\' && p[1] == '\\') + { + ret[i++] = '\\'; + p++; + } + else ret[i++] = *p; + } + ret[i] = 0; + *ret_len = i; + return ret; +} + +static BOOL seen_dir( struct dirstack *dirstack, const WCHAR *path ) +{ + UINT i; + for (i = 0; i < dirstack->num_dirs; i++) if (!strcmpW( dirstack->dirs[i], path )) return TRUE; + return FALSE; +} + +/* optimize queries of the form WHERE Name='...' [OR Name='...']* */ +static UINT seed_dirs( struct dirstack *dirstack, const struct expr *cond, WCHAR root, UINT *count ) +{ + const struct expr *left, *right; + + if (!cond || cond->type != EXPR_COMPLEX) return *count = 0; + + left = cond->u.expr.left; + right = cond->u.expr.right; + if (cond->u.expr.op == OP_EQ) + { + UINT len; + WCHAR *path; + const WCHAR *str = NULL; + + if (left->type == EXPR_PROPVAL && right->type == EXPR_SVAL && + !strcmpW( left->u.propval->name, prop_nameW ) && + toupperW( right->u.sval[0] ) == toupperW( root )) + { + str = right->u.sval; + } + else if (left->type == EXPR_SVAL && right->type == EXPR_PROPVAL && + !strcmpW( right->u.propval->name, prop_nameW ) && + toupperW( left->u.sval[0] ) == toupperW( root )) + { + str = left->u.sval; + } + if (str && (path = build_dirname( str, &len ))) + { + if (seen_dir( dirstack, path )) + { + heap_free( path ); + return ++*count; + } + else if (push_dir( dirstack, path, len )) return ++*count; + heap_free( path ); + return *count = 0; + } + } + else if (cond->u.expr.op == OP_OR) + { + UINT left_count = 0, right_count = 0; + + if (!(seed_dirs( dirstack, left, root, &left_count ))) return *count = 0; + if (!(seed_dirs( dirstack, right, root, &right_count ))) return *count = 0; + return *count += left_count + right_count; + } + return *count = 0; +} + +static WCHAR *append_path( const WCHAR *path, const WCHAR *segment, UINT *len ) +{ + UINT len_path = 0, len_segment = strlenW( segment ); + WCHAR *ret; + + *len = 0; + if (path) len_path = strlenW( path ); + if (!(ret = heap_alloc( (len_path + len_segment + 2) * sizeof(WCHAR) ))) return NULL; + if (path && len_path) + { + memcpy( ret, path, len_path * sizeof(WCHAR) ); + ret[len_path] = '\\'; + *len += len_path + 1; + } + memcpy( ret + *len, segment, len_segment * sizeof(WCHAR) ); + *len += len_segment; + ret[*len] = 0; + return ret; +} + +static WCHAR *get_file_version( const WCHAR *filename ) +{ + static const WCHAR slashW[] = {'\\',0}, fmtW[] = {'%','u','.','%','u','.','%','u','.','%','u',0}; + VS_FIXEDFILEINFO *info; + DWORD size; + void *block; + WCHAR *ret; + + if (!(ret = heap_alloc( (4 * 5 + sizeof(fmtW) / sizeof(fmtW[0])) * sizeof(WCHAR) ))) return NULL; + if (!(size = GetFileVersionInfoSizeW( filename, NULL )) || !(block = heap_alloc( size ))) + { + heap_free( ret ); + return NULL; + } + if (!GetFileVersionInfoW( filename, 0, size, block ) || + !VerQueryValueW( block, slashW, (void **)&info, &size )) + { + heap_free( block ); + heap_free( ret ); + return NULL; + } + sprintfW( ret, fmtW, info->dwFileVersionMS >> 16, info->dwFileVersionMS & 0xffff, + info->dwFileVersionLS >> 16, info->dwFileVersionLS & 0xffff ); + heap_free( block ); + return ret; +} + +static enum fill_status fill_datafile( struct table *table, const struct expr *cond ) +{ + static const WCHAR dotW[] = {'.',0}, dotdotW[] = {'.','.',0}; + struct record_datafile *rec; + UINT i, len, row = 0, offset = 0, num_expected_rows; + WCHAR *glob = NULL, *path = NULL, *new_path, root[] = {'A',':','\\',0}; + DWORD drives = GetLogicalDrives(); + WIN32_FIND_DATAW data; + HANDLE handle; + struct dirstack *dirstack; + enum fill_status status = FILL_STATUS_UNFILTERED; + + if (!resize_table( table, 8, sizeof(*rec) )) return FILL_STATUS_FAILED; + + dirstack = alloc_dirstack(2); + + for (i = 0; i < 26; i++) + { + if (!(drives & (1 << i))) continue; + + root[0] = 'A' + i; + if (GetDriveTypeW( root ) != DRIVE_FIXED) continue; + + num_expected_rows = 0; + if (!seed_dirs( dirstack, cond, root[0], &num_expected_rows )) clear_dirstack( dirstack ); + + for (;;) + { + heap_free( glob ); + heap_free( path ); + path = pop_dir( dirstack, &len ); + if (!(glob = build_glob( root[0], path, len ))) + { + status = FILL_STATUS_FAILED; + goto done; + } + if ((handle = FindFirstFileW( glob, &data )) != INVALID_HANDLE_VALUE) + { + do + { + if (!resize_table( table, row + 1, sizeof(*rec) )) + { + status = FILL_STATUS_FAILED; + FindClose( handle ); + goto done; + } + if (!strcmpW( data.cFileName, dotW ) || !strcmpW( data.cFileName, dotdotW )) continue; + new_path = append_path( path, data.cFileName, &len ); + + if (data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) + { + if (push_dir( dirstack, new_path, len )) continue; + heap_free( new_path ); + FindClose( handle ); + status = FILL_STATUS_FAILED; + goto done; + } + rec = (struct record_datafile *)(table->data + offset); + rec->name = build_name( root[0], new_path ); + rec->version = get_file_version( rec->name ); + if (!match_row( table, row, cond, &status )) + { + free_row_values( table, row ); + continue; + } + else if (num_expected_rows && row == num_expected_rows - 1) + { + row++; + FindClose( handle ); + status = FILL_STATUS_FILTERED; + goto done; + } + offset += sizeof(*rec); + row++; + } + while (FindNextFileW( handle, &data )); + FindClose( handle ); + } + if (!peek_dir( dirstack )) break; + } + } + +done: + free_dirstack( dirstack ); + heap_free( glob ); + heap_free( path ); + + TRACE("created %u rows\n", row); + table->num_rows = row; + return status; +} + +static UINT32 get_pixelsperxlogicalinch(void) +{ + HDC hdc = GetDC( NULL ); + UINT32 ret; + + if (!hdc) return 96; + ret = GetDeviceCaps( hdc, LOGPIXELSX ); + ReleaseDC( NULL, hdc ); + return ret; +} + +static enum fill_status fill_desktopmonitor( struct table *table, const struct expr *cond ) +{ + struct record_desktopmonitor *rec; + enum fill_status status = FILL_STATUS_UNFILTERED; + UINT row = 0; + + if (!resize_table( table, 1, sizeof(*rec) )) return FILL_STATUS_FAILED; + + rec = (struct record_desktopmonitor *)table->data; + rec->pixelsperxlogicalinch = get_pixelsperxlogicalinch(); + + if (match_row( table, row, cond, &status )) row++; + + TRACE("created %u rows\n", row); + table->num_rows = row; + return status; +} + +static enum fill_status fill_directory( struct table *table, const struct expr *cond ) +{ + static const WCHAR dotW[] = {'.',0}, dotdotW[] = {'.','.',0}; + struct record_directory *rec; + UINT i, len, row = 0, offset = 0, num_expected_rows; + WCHAR *glob = NULL, *path = NULL, *new_path, root[] = {'A',':','\\',0}; + DWORD drives = GetLogicalDrives(); + WIN32_FIND_DATAW data; + HANDLE handle; + struct dirstack *dirstack; + enum fill_status status = FILL_STATUS_UNFILTERED; + + if (!resize_table( table, 4, sizeof(*rec) )) return FILL_STATUS_FAILED; + + dirstack = alloc_dirstack(2); + + for (i = 0; i < 26; i++) + { + if (!(drives & (1 << i))) continue; + + root[0] = 'A' + i; + if (GetDriveTypeW( root ) != DRIVE_FIXED) continue; + + num_expected_rows = 0; + if (!seed_dirs( dirstack, cond, root[0], &num_expected_rows )) clear_dirstack( dirstack ); + + for (;;) + { + heap_free( glob ); + heap_free( path ); + path = pop_dir( dirstack, &len ); + if (!(glob = build_glob( root[0], path, len ))) + { + status = FILL_STATUS_FAILED; + goto done; + } + if ((handle = FindFirstFileW( glob, &data )) != INVALID_HANDLE_VALUE) + { + do + { + if (!resize_table( table, row + 1, sizeof(*rec) )) + { + FindClose( handle ); + status = FILL_STATUS_FAILED; + goto done; + } + if (!(data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) || + !strcmpW( data.cFileName, dotW ) || !strcmpW( data.cFileName, dotdotW )) + continue; + + new_path = append_path( path, data.cFileName, &len ); + if (!(push_dir( dirstack, new_path, len ))) + { + heap_free( new_path ); + FindClose( handle ); + status = FILL_STATUS_FAILED; + goto done; + } + rec = (struct record_directory *)(table->data + offset); + rec->accessmask = FILE_ALL_ACCESS; + rec->name = build_name( root[0], new_path ); + if (!match_row( table, row, cond, &status )) + { + free_row_values( table, row ); + continue; + } + else if (num_expected_rows && row == num_expected_rows - 1) + { + row++; + FindClose( handle ); + status = FILL_STATUS_FILTERED; + goto done; + } + offset += sizeof(*rec); + row++; + } + while (FindNextFileW( handle, &data )); + FindClose( handle ); + } + if (!peek_dir( dirstack )) break; + } + } + +done: + free_dirstack( dirstack ); + heap_free( glob ); + heap_free( path ); + + TRACE("created %u rows\n", row); + table->num_rows = row; + return status; +} + +static UINT64 get_freespace( const WCHAR *dir, UINT64 *disksize ) +{ + WCHAR root[] = {'\\','\\','.','\\','A',':',0}; + ULARGE_INTEGER free; + DISK_GEOMETRY_EX info; + HANDLE handle; + DWORD bytes_returned; + + free.QuadPart = 512 * 1024 * 1024; + GetDiskFreeSpaceExW( dir, NULL, NULL, &free ); + + root[4] = dir[0]; + handle = CreateFileW( root, GENERIC_READ, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, 0 ); + if (handle != INVALID_HANDLE_VALUE) + { + if (DeviceIoControl( handle, IOCTL_DISK_GET_DRIVE_GEOMETRY_EX, NULL, 0, &info, sizeof(info), &bytes_returned, NULL )) + *disksize = info.DiskSize.QuadPart; + CloseHandle( handle ); + } + return free.QuadPart; +} + +static enum fill_status fill_diskdrive( struct table *table, const struct expr *cond ) +{ + static const WCHAR fmtW[] = + {'\\','\\','\\','\\','.','\\','\\','P','H','Y','S','I','C','A','L','D','R','I','V','E','%','u',0}; + WCHAR device_id[sizeof(fmtW)/sizeof(fmtW[0]) + 10], root[] = {'A',':','\\',0}; + struct record_diskdrive *rec; + UINT i, row = 0, offset = 0, index = 0, type; + UINT64 size = 1024 * 1024 * 1024; + DWORD drives = GetLogicalDrives(); + enum fill_status status = FILL_STATUS_UNFILTERED; + + if (!resize_table( table, 2, sizeof(*rec) )) return FILL_STATUS_FAILED; + + for (i = 0; i < 26; i++) + { + if (drives & (1 << i)) + { + root[0] = 'A' + i; + type = GetDriveTypeW( root ); + if (type != DRIVE_FIXED && type != DRIVE_REMOVABLE) + continue; + + if (!resize_table( table, row + 1, sizeof(*rec) )) return FILL_STATUS_FAILED; + + rec = (struct record_diskdrive *)(table->data + offset); + sprintfW( device_id, fmtW, index ); + rec->device_id = heap_strdupW( device_id ); + rec->index = index; + rec->interfacetype = diskdrive_interfacetypeW; + rec->manufacturer = diskdrive_manufacturerW; + if (type == DRIVE_FIXED) + rec->mediatype = diskdrive_mediatype_fixedW; + else + rec->mediatype = diskdrive_mediatype_removableW; + rec->model = diskdrive_modelW; + rec->pnpdevice_id = diskdrive_pnpdeviceidW; + rec->serialnumber = diskdrive_serialW; + get_freespace( root, &size ); + rec->size = size; + if (!match_row( table, row, cond, &status )) + { + free_row_values( table, row ); + continue; + } + offset += sizeof(*rec); + index++; + row++; + } + } + TRACE("created %u rows\n", row); + table->num_rows = row; + return status; +} + +static WCHAR *get_filesystem( const WCHAR *root ) +{ + static const WCHAR ntfsW[] = {'N','T','F','S',0}; + WCHAR buffer[MAX_PATH + 1]; + + if (GetVolumeInformationW( root, NULL, 0, NULL, NULL, NULL, buffer, MAX_PATH + 1 )) + return heap_strdupW( buffer ); + return heap_strdupW( ntfsW ); +} + +static enum fill_status fill_diskpartition( struct table *table, const struct expr *cond ) +{ + static const WCHAR fmtW[] = + {'D','i','s','k',' ','#','%','u',',',' ','P','a','r','t','i','t','i','o','n',' ','#','0',0}; + WCHAR device_id[32], root[] = {'A',':','\\',0}; + struct record_diskpartition *rec; + UINT i, row = 0, offset = 0, type, index = 0; + UINT64 size = 1024 * 1024 * 1024; + DWORD drives = GetLogicalDrives(); + enum fill_status status = FILL_STATUS_UNFILTERED; + + if (!resize_table( table, 4, sizeof(*rec) )) return FILL_STATUS_FAILED; + + for (i = 0; i < 26; i++) + { + if (drives & (1 << i)) + { + root[0] = 'A' + i; + type = GetDriveTypeW( root ); + if (type != DRIVE_FIXED && type != DRIVE_REMOVABLE) + continue; + + if (!resize_table( table, row + 1, sizeof(*rec) )) return FILL_STATUS_FAILED; + + rec = (struct record_diskpartition *)(table->data + offset); + rec->bootable = (i == 2) ? -1 : 0; + rec->bootpartition = (i == 2) ? -1 : 0; + sprintfW( device_id, fmtW, index ); + rec->device_id = heap_strdupW( device_id ); + rec->diskindex = index; + rec->index = 0; + rec->pnpdevice_id = heap_strdupW( device_id ); + get_freespace( root, &size ); + rec->size = size; + rec->startingoffset = 0; + rec->type = get_filesystem( root ); + if (!match_row( table, row, cond, &status )) + { + free_row_values( table, row ); + continue; + } + offset += sizeof(*rec); + row++; + index++; + } + } + TRACE("created %u rows\n", row); + table->num_rows = row; + return status; +} + +static WCHAR *get_volumename( const WCHAR *root ) +{ + WCHAR buf[MAX_PATH + 1] = {0}; + GetVolumeInformationW( root, buf, sizeof(buf)/sizeof(buf[0]), NULL, NULL, NULL, NULL, 0 ); + return heap_strdupW( buf ); +} +static WCHAR *get_volumeserialnumber( const WCHAR *root ) +{ + static const WCHAR fmtW[] = {'%','0','8','X',0}; + DWORD serial = 0; + WCHAR buffer[9]; + + GetVolumeInformationW( root, NULL, 0, &serial, NULL, NULL, NULL, 0 ); + sprintfW( buffer, fmtW, serial ); + return heap_strdupW( buffer ); +} + +static enum fill_status fill_logicaldisk( struct table *table, const struct expr *cond ) +{ + static const WCHAR fmtW[] = {'%','c',':',0}; + WCHAR device_id[3], root[] = {'A',':','\\',0}; + struct record_logicaldisk *rec; + UINT i, row = 0, offset = 0, type; + UINT64 size = 1024 * 1024 * 1024; + DWORD drives = GetLogicalDrives(); + enum fill_status status = FILL_STATUS_UNFILTERED; + + if (!resize_table( table, 4, sizeof(*rec) )) return FILL_STATUS_FAILED; + + for (i = 0; i < 26; i++) + { + if (drives & (1 << i)) + { + root[0] = 'A' + i; + type = GetDriveTypeW( root ); + if (type != DRIVE_FIXED && type != DRIVE_CDROM && type != DRIVE_REMOVABLE) + continue; + + if (!resize_table( table, row + 1, sizeof(*rec) )) return FILL_STATUS_FAILED; + + rec = (struct record_logicaldisk *)(table->data + offset); + sprintfW( device_id, fmtW, 'A' + i ); + rec->device_id = heap_strdupW( device_id ); + rec->drivetype = type; + rec->filesystem = get_filesystem( root ); + rec->freespace = get_freespace( root, &size ); + rec->name = heap_strdupW( device_id ); + rec->size = size; + rec->volumename = get_volumename( root ); + rec->volumeserialnumber = get_volumeserialnumber( root ); + if (!match_row( table, row, cond, &status )) + { + free_row_values( table, row ); + continue; + } + offset += sizeof(*rec); + row++; + } + } + TRACE("created %u rows\n", row); + table->num_rows = row; + return status; +} + +static UINT16 get_connection_status( IF_OPER_STATUS status ) +{ + switch (status) + { + case IfOperStatusDown: + return 0; /* Disconnected */ + case IfOperStatusUp: + return 2; /* Connected */ + default: + ERR("unhandled status %u\n", status); + break; + } + return 0; +} +static WCHAR *get_mac_address( const BYTE *addr, DWORD len ) +{ + static const WCHAR fmtW[] = + {'%','0','2','x',':','%','0','2','x',':','%','0','2','x',':', + '%','0','2','x',':','%','0','2','x',':','%','0','2','x',0}; + WCHAR *ret; + + if (len != 6 || !(ret = heap_alloc( 18 * sizeof(WCHAR) ))) return NULL; + sprintfW( ret, fmtW, addr[0], addr[1], addr[2], addr[3], addr[4], addr[5] ); + return ret; +} +static const WCHAR *get_adaptertype( DWORD type, int *physical ) +{ + static const WCHAR ethernetW[] = {'E','t','h','e','r','n','e','t',' ','8','0','2','.','3',0}; + static const WCHAR wirelessW[] = {'W','i','r','e','l','e','s','s',0}; + static const WCHAR firewireW[] = {'1','3','9','4',0}; + static const WCHAR tunnelW[] = {'T','u','n','n','e','l',0}; + + switch (type) + { + case IF_TYPE_ETHERNET_CSMACD: *physical = -1; return ethernetW; + case IF_TYPE_IEEE80211: *physical = -1; return wirelessW; + case IF_TYPE_IEEE1394: *physical = -1; return firewireW; + case IF_TYPE_TUNNEL: *physical = 0; return tunnelW; + default: *physical = 0; return NULL; + } +} + +static enum fill_status fill_networkadapter( struct table *table, const struct expr *cond ) +{ + static const WCHAR fmtW[] = {'%','u',0}; + WCHAR device_id[11]; + struct record_networkadapter *rec; + IP_ADAPTER_ADDRESSES *aa, *buffer; + UINT row = 0, offset = 0, count = 0; + DWORD size = 0, ret; + int physical; + enum fill_status status = FILL_STATUS_UNFILTERED; + + ret = GetAdaptersAddresses( AF_UNSPEC, 0, NULL, NULL, &size ); + if (ret != ERROR_BUFFER_OVERFLOW) return FILL_STATUS_FAILED; + + if (!(buffer = heap_alloc( size ))) return FILL_STATUS_FAILED; + if (GetAdaptersAddresses( AF_UNSPEC, 0, NULL, buffer, &size )) + { + heap_free( buffer ); + return FILL_STATUS_FAILED; + } + for (aa = buffer; aa; aa = aa->Next) + { + if (aa->IfType != IF_TYPE_SOFTWARE_LOOPBACK) count++; + } + if (!resize_table( table, count, sizeof(*rec) )) + { + heap_free( buffer ); + return FILL_STATUS_FAILED; + } + for (aa = buffer; aa; aa = aa->Next) + { + if (aa->IfType == IF_TYPE_SOFTWARE_LOOPBACK) continue; + + rec = (struct record_networkadapter *)(table->data + offset); + sprintfW( device_id, fmtW, aa->u.s.IfIndex ); + rec->adaptertype = get_adaptertype( aa->IfType, &physical ); + rec->device_id = heap_strdupW( device_id ); + rec->index = aa->u.s.IfIndex; + rec->interface_index = aa->u.s.IfIndex; + rec->mac_address = get_mac_address( aa->PhysicalAddress, aa->PhysicalAddressLength ); + rec->manufacturer = compsys_manufacturerW; + rec->name = heap_strdupW( aa->FriendlyName ); + rec->netconnection_status = get_connection_status( aa->OperStatus ); + rec->physicaladapter = physical; + rec->pnpdevice_id = networkadapter_pnpdeviceidW; + rec->speed = 1000000; + if (!match_row( table, row, cond, &status )) + { + free_row_values( table, row ); + continue; + } + offset += sizeof(*rec); + row++; + } + TRACE("created %u rows\n", row); + table->num_rows = row; + + heap_free( buffer ); + return status; +} + +static WCHAR *get_dnshostname( IP_ADAPTER_UNICAST_ADDRESS *addr ) +{ + const SOCKET_ADDRESS *sa = &addr->Address; + WCHAR buf[NI_MAXHOST]; + + if (!addr) return NULL; + if (GetNameInfoW( sa->lpSockaddr, sa->iSockaddrLength, buf, sizeof(buf)/sizeof(buf[0]), NULL, + 0, NI_NAMEREQD )) return NULL; + return heap_strdupW( buf ); +} +static struct array *get_defaultipgateway( IP_ADAPTER_GATEWAY_ADDRESS *list ) +{ + IP_ADAPTER_GATEWAY_ADDRESS *gateway; + struct array *ret; + ULONG buflen, i = 0, count = 0; + WCHAR **ptr, buf[54]; /* max IPv6 address length */ + + if (!list) return NULL; + for (gateway = list; gateway; gateway = gateway->Next) count++; + + if (!(ret = heap_alloc( sizeof(*ret) ))) return NULL; + if (!(ptr = heap_alloc( sizeof(*ptr) * count ))) + { + heap_free( ret ); + return NULL; + } + for (gateway = list; gateway; gateway = gateway->Next) + { + buflen = sizeof(buf)/sizeof(buf[0]); + if (WSAAddressToStringW( gateway->Address.lpSockaddr, gateway->Address.iSockaddrLength, + NULL, buf, &buflen) || !(ptr[i++] = heap_strdupW( buf ))) + { + for (; i > 0; i--) heap_free( ptr[i - 1] ); + heap_free( ptr ); + heap_free( ret ); + return NULL; + } + } + ret->count = count; + ret->ptr = ptr; + return ret; +} +static struct array *get_dnsserversearchorder( IP_ADAPTER_DNS_SERVER_ADDRESS *list ) +{ + IP_ADAPTER_DNS_SERVER_ADDRESS *server; + struct array *ret; + ULONG buflen, i = 0, count = 0; + WCHAR **ptr, *p, buf[54]; /* max IPv6 address length */ + + if (!list) return NULL; + for (server = list; server; server = server->Next) count++; + + if (!(ret = heap_alloc( sizeof(*ret) ))) return NULL; + if (!(ptr = heap_alloc( sizeof(*ptr) * count ))) + { + heap_free( ret ); + return NULL; + } + for (server = list; server; server = server->Next) + { + buflen = sizeof(buf)/sizeof(buf[0]); + if (WSAAddressToStringW( server->Address.lpSockaddr, server->Address.iSockaddrLength, + NULL, buf, &buflen) || !(ptr[i++] = heap_strdupW( buf ))) + { + for (; i > 0; i--) heap_free( ptr[i - 1] ); + heap_free( ptr ); + heap_free( ret ); + return NULL; + } + if ((p = strrchrW( ptr[i - 1], ':' ))) *p = 0; + } + ret->count = count; + ret->ptr = ptr; + return ret; +} +static WCHAR *get_settingid( UINT32 index ) +{ + GUID guid; + WCHAR *ret, *str; + memset( &guid, 0, sizeof(guid) ); + guid.Data1 = index; + UuidToStringW( &guid, &str ); + ret = heap_strdupW( str ); + RpcStringFreeW( &str ); + return ret; +} + +static enum fill_status fill_networkadapterconfig( struct table *table, const struct expr *cond ) +{ + struct record_networkadapterconfig *rec; + IP_ADAPTER_ADDRESSES *aa, *buffer; + UINT row = 0, offset = 0, count = 0; + DWORD size = 0, ret; + enum fill_status status = FILL_STATUS_UNFILTERED; + + ret = GetAdaptersAddresses( AF_UNSPEC, GAA_FLAG_INCLUDE_ALL_GATEWAYS, NULL, NULL, &size ); + if (ret != ERROR_BUFFER_OVERFLOW) return FILL_STATUS_FAILED; + + if (!(buffer = heap_alloc( size ))) return FILL_STATUS_FAILED; + if (GetAdaptersAddresses( AF_UNSPEC, GAA_FLAG_INCLUDE_ALL_GATEWAYS, NULL, buffer, &size )) + { + heap_free( buffer ); + return FILL_STATUS_FAILED; + } + for (aa = buffer; aa; aa = aa->Next) + { + if (aa->IfType != IF_TYPE_SOFTWARE_LOOPBACK) count++; + } + if (!resize_table( table, count, sizeof(*rec) )) + { + heap_free( buffer ); + return FILL_STATUS_FAILED; + } + for (aa = buffer; aa; aa = aa->Next) + { + if (aa->IfType == IF_TYPE_SOFTWARE_LOOPBACK) continue; + + rec = (struct record_networkadapterconfig *)(table->data + offset); + rec->defaultipgateway = get_defaultipgateway( aa->FirstGatewayAddress ); + rec->description = heap_strdupW( aa->Description ); + rec->dhcpenabled = -1; + rec->dnshostname = get_dnshostname( aa->FirstUnicastAddress ); + rec->dnsserversearchorder = get_dnsserversearchorder( aa->FirstDnsServerAddress ); + rec->index = aa->u.s.IfIndex; + rec->ipconnectionmetric = 20; + rec->ipenabled = -1; + rec->mac_address = get_mac_address( aa->PhysicalAddress, aa->PhysicalAddressLength ); + rec->settingid = get_settingid( rec->index ); + if (!match_row( table, row, cond, &status )) + { + free_row_values( table, row ); + continue; + } + offset += sizeof(*rec); + row++; + } + TRACE("created %u rows\n", row); + table->num_rows = row; + + heap_free( buffer ); + return status; +} + +static enum fill_status fill_physicalmemory( struct table *table, const struct expr *cond ) +{ + struct record_physicalmemory *rec; + enum fill_status status = FILL_STATUS_UNFILTERED; + UINT row = 0; + + if (!resize_table( table, 1, sizeof(*rec) )) return FILL_STATUS_FAILED; + + rec = (struct record_physicalmemory *)table->data; + rec->capacity = get_total_physical_memory(); + if (!match_row( table, row, cond, &status )) free_row_values( table, row ); + else row++; + + TRACE("created %u rows\n", row); + table->num_rows = row; + return status; +} + +static enum fill_status fill_printer( struct table *table, const struct expr *cond ) +{ + static const WCHAR fmtW[] = {'P','r','i','n','t','e','r','%','d',0}; + struct record_printer *rec; + enum fill_status status = FILL_STATUS_UNFILTERED; + PRINTER_INFO_2W *info; + DWORD i, offset = 0, count = 0, size = 0; + WCHAR id[20]; + + EnumPrintersW( PRINTER_ENUM_LOCAL, NULL, 2, NULL, 0, &size, &count ); + if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) return FILL_STATUS_FAILED; + + if (!(info = heap_alloc( size ))) return FILL_STATUS_FAILED; + if (!EnumPrintersW( PRINTER_ENUM_LOCAL, NULL, 2, (BYTE *)info, size, &size, &count )) + { + heap_free( info ); + return FILL_STATUS_FAILED; + } + if (!resize_table( table, count, sizeof(*rec) )) + { + heap_free( info ); + return FILL_STATUS_FAILED; + } + + for (i = 0; i < count; i++) + { + rec = (struct record_printer *)(table->data + offset); + rec->attributes = info[i].Attributes; + rec->drivername = heap_strdupW( info[i].pDriverName ); + rec->horizontalresolution = info[i].pDevMode->u1.s1.dmPrintQuality; + rec->local = -1; + rec->name = heap_strdupW( info[i].pPrinterName ); + rec->network = 0; + sprintfW( id, fmtW, i ); + rec->device_id = heap_strdupW( id ); + rec->portname = heap_strdupW( info[i].pPortName ); + rec->location = heap_strdupW( info[i].pLocation ); + if (!match_row( table, i, cond, &status )) + { + free_row_values( table, i ); + continue; + } + offset += sizeof(*rec); + } + TRACE("created %u rows\n", count); + table->num_rows = count; + + heap_free( info ); + return status; +} + +static WCHAR *get_cmdline( DWORD process_id ) +{ + if (process_id == GetCurrentProcessId()) return heap_strdupW( GetCommandLineW() ); + return NULL; /* FIXME handle different process case */ +} + +static enum fill_status fill_process( struct table *table, const struct expr *cond ) +{ + static const WCHAR fmtW[] = {'%','u',0}; + WCHAR handle[11]; + struct record_process *rec; + PROCESSENTRY32W entry; + HANDLE snap; + enum fill_status status = FILL_STATUS_FAILED; + UINT row = 0, offset = 0; + + snap = CreateToolhelp32Snapshot( TH32CS_SNAPPROCESS, 0 ); + if (snap == INVALID_HANDLE_VALUE) return FILL_STATUS_FAILED; + + entry.dwSize = sizeof(entry); + if (!Process32FirstW( snap, &entry )) goto done; + if (!resize_table( table, 8, sizeof(*rec) )) goto done; + + do + { + if (!resize_table( table, row + 1, sizeof(*rec) )) goto done; + + rec = (struct record_process *)(table->data + offset); + rec->caption = heap_strdupW( entry.szExeFile ); + rec->commandline = get_cmdline( entry.th32ProcessID ); + rec->description = heap_strdupW( entry.szExeFile ); + sprintfW( handle, fmtW, entry.th32ProcessID ); + rec->handle = heap_strdupW( handle ); + rec->name = heap_strdupW( entry.szExeFile ); + rec->process_id = entry.th32ProcessID; + rec->pprocess_id = entry.th32ParentProcessID; + rec->thread_count = entry.cntThreads; + rec->workingsetsize = 0; + rec->get_owner = process_get_owner; + if (!match_row( table, row, cond, &status )) + { + free_row_values( table, row ); + continue; + } + offset += sizeof(*rec); + row++; + } while (Process32NextW( snap, &entry )); + + TRACE("created %u rows\n", row); + table->num_rows = row; + status = FILL_STATUS_UNFILTERED; + +done: + CloseHandle( snap ); + return status; +} + +static inline void do_cpuid( unsigned int ax, unsigned int *p ) +{ +#ifdef __i386__ +#ifdef _MSC_VER + __cpuid(p, ax); +#else + __asm__("pushl %%ebx\n\t" + "cpuid\n\t" + "movl %%ebx, %%esi\n\t" + "popl %%ebx" + : "=a" (p[0]), "=S" (p[1]), "=c" (p[2]), "=d" (p[3]) + : "0" (ax)); +#endif +#endif +} +static const WCHAR *get_osarchitecture(void) +{ + SYSTEM_INFO info; + GetNativeSystemInfo( &info ); + if (info.u.s.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64) return os_64bitW; + return os_32bitW; +} +static void get_processor_caption( WCHAR *caption ) +{ + static const WCHAR fmtW[] = + {'%','s',' ','F','a','m','i','l','y',' ','%','u',' ', + 'M','o','d','e','l',' ','%','u',' ','S','t','e','p','p','i','n','g',' ','%','u',0}; + static const WCHAR x86W[] = {'x','8','6',0}; + static const WCHAR intel64W[] = {'I','n','t','e','l','6','4',0}; + const WCHAR *arch = (get_osarchitecture() == os_32bitW) ? x86W : intel64W; + unsigned int regs[4] = {0, 0, 0, 0}; + + do_cpuid( 1, regs ); + sprintfW( caption, fmtW, arch, (regs[0] & (15 << 8)) >> 8, (regs[0] & (15 << 4)) >> 4, regs[0] & 15 ); +} +static void get_processor_version( WCHAR *version ) +{ + static const WCHAR fmtW[] = + {'M','o','d','e','l',' ','%','u',',',' ','S','t','e','p','p','i','n','g',' ','%','u',0}; + unsigned int regs[4] = {0, 0, 0, 0}; + + do_cpuid( 1, regs ); + sprintfW( version, fmtW, (regs[0] & (15 << 4)) >> 4, regs[0] & 15 ); +} +static void get_processor_id( WCHAR *processor_id ) +{ + static const WCHAR fmtW[] = {'%','0','8','X','%','0','8','X',0}; + unsigned int regs[4] = {0, 0, 0, 0}; + + do_cpuid( 1, regs ); + sprintfW( processor_id, fmtW, regs[3], regs[0] ); +} +static void regs_to_str( unsigned int *regs, unsigned int len, WCHAR *buffer ) +{ + unsigned int i; + unsigned char *p = (unsigned char *)regs; + + for (i = 0; i < len; i++) { buffer[i] = *p++; } + buffer[i] = 0; +} +static void get_processor_manufacturer( WCHAR *manufacturer ) +{ + unsigned int tmp, regs[4] = {0, 0, 0, 0}; + + do_cpuid( 0, regs ); + tmp = regs[2]; /* swap edx and ecx */ + regs[2] = regs[3]; + regs[3] = tmp; + + regs_to_str( regs + 1, 12, manufacturer ); +} +static void get_processor_name( WCHAR *name ) +{ + unsigned int regs[4] = {0, 0, 0, 0}; + + do_cpuid( 0x80000000, regs ); + if (regs[0] >= 0x80000004) + { + do_cpuid( 0x80000002, regs ); + regs_to_str( regs, 16, name ); + do_cpuid( 0x80000003, regs ); + regs_to_str( regs, 16, name + 16 ); + do_cpuid( 0x80000004, regs ); + regs_to_str( regs, 16, name + 32 ); + } +} +static UINT get_processor_currentclockspeed( UINT index ) +{ + PROCESSOR_POWER_INFORMATION *info; + UINT ret = 1000, size = get_processor_count() * sizeof(PROCESSOR_POWER_INFORMATION); + NTSTATUS status; + + if ((info = heap_alloc( size ))) + { + status = NtPowerInformation( ProcessorInformation, NULL, 0, info, size ); + if (!status) ret = info[index].CurrentMhz; + heap_free( info ); + } + return ret; +} +static UINT get_processor_maxclockspeed( UINT index ) +{ + PROCESSOR_POWER_INFORMATION *info; + UINT ret = 1000, size = get_processor_count() * sizeof(PROCESSOR_POWER_INFORMATION); + NTSTATUS status; + + if ((info = heap_alloc( size ))) + { + status = NtPowerInformation( ProcessorInformation, NULL, 0, info, size ); + if (!status) ret = info[index].MaxMhz; + heap_free( info ); + } + return ret; +} + +static enum fill_status fill_processor( struct table *table, const struct expr *cond ) +{ + static const WCHAR fmtW[] = {'C','P','U','%','u',0}; + WCHAR caption[100], device_id[14], processor_id[17], manufacturer[13], name[49] = {0}, version[50]; + struct record_processor *rec; + UINT i, offset = 0, num_cores, num_logical_processors, count = get_processor_count(); + enum fill_status status = FILL_STATUS_UNFILTERED; + + if (!resize_table( table, count, sizeof(*rec) )) return FILL_STATUS_FAILED; + + get_processor_caption( caption ); + get_processor_id( processor_id ); + get_processor_manufacturer( manufacturer ); + get_processor_name( name ); + get_processor_version( version ); + + num_logical_processors = get_logical_processor_count( &num_cores ) / count; + num_cores /= count; + + for (i = 0; i < count; i++) + { + rec = (struct record_processor *)(table->data + offset); + rec->addresswidth = get_osarchitecture() == os_32bitW ? 32 : 64; + rec->caption = heap_strdupW( caption ); + rec->cpu_status = 1; /* CPU Enabled */ + rec->currentclockspeed = get_processor_currentclockspeed( i ); + rec->datawidth = get_osarchitecture() == os_32bitW ? 32 : 64; + rec->description = heap_strdupW( caption ); + sprintfW( device_id, fmtW, i ); + rec->device_id = heap_strdupW( device_id ); + rec->family = 2; /* Unknown */ + rec->manufacturer = heap_strdupW( manufacturer ); + rec->maxclockspeed = get_processor_maxclockspeed( i ); + rec->name = heap_strdupW( name ); + rec->num_cores = num_cores; + rec->num_logical_processors = num_logical_processors; + rec->processor_id = heap_strdupW( processor_id ); + rec->processortype = 3; /* central processor */ + rec->unique_id = NULL; + rec->version = heap_strdupW( version ); + if (!match_row( table, i, cond, &status )) + { + free_row_values( table, i ); + continue; + } + offset += sizeof(*rec); + } + + TRACE("created %u rows\n", count); + table->num_rows = count; + return status; +} + +static WCHAR *get_lastbootuptime(void) +{ + static const WCHAR fmtW[] = + {'%','0','4','u','%','0','2','u','%','0','2','u','%','0','2','u','%','0','2','u','%','0','2','u', + '.','%','0','6','u','+','0','0','0',0}; + SYSTEM_TIMEOFDAY_INFORMATION ti; + TIME_FIELDS tf; + WCHAR *ret; + + if (!(ret = heap_alloc( 26 * sizeof(WCHAR) ))) return NULL; + + NtQuerySystemInformation( SystemTimeOfDayInformation, &ti, sizeof(ti), NULL ); + RtlTimeToTimeFields( &ti.liKeBootTime, &tf ); + sprintfW( ret, fmtW, tf.Year, tf.Month, tf.Day, tf.Hour, tf.Minute, tf.Second, tf.Milliseconds * 1000 ); + return ret; +} +static WCHAR *get_localdatetime(void) +{ + static const WCHAR fmtW[] = + {'%','0','4','u','%','0','2','u','%','0','2','u','%','0','2','u','%','0','2','u','%','0','2','u', + '.','%','0','6','u','%','+','0','3','d',0}; + TIME_ZONE_INFORMATION tzi; + SYSTEMTIME st; + WCHAR *ret; + DWORD Status; + LONG Bias; + + Status = GetTimeZoneInformation(&tzi); + + if(Status == TIME_ZONE_ID_INVALID) return NULL; + Bias = tzi.Bias; + if(Status == TIME_ZONE_ID_DAYLIGHT) + Bias+= tzi.DaylightBias; + else + Bias+= tzi.StandardBias; + if (!(ret = heap_alloc( 26 * sizeof(WCHAR) ))) return NULL; + + GetLocalTime(&st); + sprintfW( ret, fmtW, st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond, st.wMilliseconds * 1000, -Bias); + return ret; +} +static WCHAR *get_systemdirectory(void) +{ + void *redir; + WCHAR *ret; + + if (!(ret = heap_alloc( MAX_PATH * sizeof(WCHAR) ))) return NULL; + Wow64DisableWow64FsRedirection( &redir ); + GetSystemDirectoryW( ret, MAX_PATH ); + Wow64RevertWow64FsRedirection( redir ); + return ret; +} +static WCHAR *get_codeset(void) +{ + static const WCHAR fmtW[] = {'%','u',0}; + WCHAR *ret = heap_alloc( 11 * sizeof(WCHAR) ); + if (ret) sprintfW( ret, fmtW, GetACP() ); + return ret; +} +static WCHAR *get_countrycode(void) +{ + WCHAR *ret = heap_alloc( 6 * sizeof(WCHAR) ); + if (ret) GetLocaleInfoW( LOCALE_SYSTEM_DEFAULT, LOCALE_ICOUNTRY, ret, 6 ); + return ret; +} +static WCHAR *get_locale(void) +{ + WCHAR *ret = heap_alloc( 5 * sizeof(WCHAR) ); + if (ret) GetLocaleInfoW( LOCALE_SYSTEM_DEFAULT, LOCALE_ILANGUAGE, ret, 5 ); + return ret; +} +static WCHAR *get_osbuildnumber( OSVERSIONINFOEXW *ver ) +{ + static const WCHAR fmtW[] = {'%','u',0}; + WCHAR *ret = heap_alloc( 11 * sizeof(WCHAR) ); + if (ret) sprintfW( ret, fmtW, ver->dwBuildNumber ); + return ret; +} +static WCHAR *get_oscaption( OSVERSIONINFOEXW *ver ) +{ + static const WCHAR windowsW[] = + {'M','i','c','r','o','s','o','f','t',' ','W','i','n','d','o','w','s',' '}; + static const WCHAR win2000W[] = + {'2','0','0','0',' ','P','r','o','f','e','s','s','i','o','n','a','l',0}; + static const WCHAR win2003W[] = + {'S','e','r','v','e','r',' ','2','0','0','3',' ','S','t','a','n','d','a','r','d',' ','E','d','i','t','i','o','n',0}; + static const WCHAR winxpW[] = + {'X','P',' ','P','r','o','f','e','s','s','i','o','n','a','l',0}; + static const WCHAR winxp64W[] = + {'X','P',' ','P','r','o','f','e','s','s','i','o','n','a','l',' ','x','6','4',' ','E','d','i','t','i','o','n',0}; + static const WCHAR vistaW[] = + {'V','i','s','t','a',' ','U','l','t','i','m','a','t','e',0}; + static const WCHAR win2008W[] = + {'S','e','r','v','e','r',' ','2','0','0','8',' ','S','t','a','n','d','a','r','d',0}; + static const WCHAR win7W[] = + {'7',' ','P','r','o','f','e','s','s','i','o','n','a','l',0}; + static const WCHAR win2008r2W[] = + {'S','e','r','v','e','r',' ','2','0','0','8',' ','R','2',' ','S','t','a','n','d','a','r','d',0}; + static const WCHAR win8W[] = + {'8',' ','P','r','o',0}; + static const WCHAR win81W[] = + {'8','.','1',' ','P','r','o',0}; + static const WCHAR win10W[] = + {'1','0',' ','P','r','o',0}; + int len = sizeof(windowsW)/sizeof(windowsW[0]); + WCHAR *ret; + + if (!(ret = heap_alloc( len * sizeof(WCHAR) + sizeof(win2003W) ))) return NULL; + memcpy( ret, windowsW, sizeof(windowsW) ); + if (ver->dwMajorVersion == 10 && ver->dwMinorVersion == 0) memcpy( ret + len, win10W, sizeof(win10W) ); + else if (ver->dwMajorVersion == 6 && ver->dwMinorVersion == 3) memcpy( ret + len, win8W, sizeof(win8W) ); + else if (ver->dwMajorVersion == 6 && ver->dwMinorVersion == 2) memcpy( ret + len, win81W, sizeof(win81W) ); + else if (ver->dwMajorVersion == 6 && ver->dwMinorVersion == 1) + { + if (ver->wProductType == VER_NT_WORKSTATION) memcpy( ret + len, win7W, sizeof(win7W) ); + else memcpy( ret + len, win2008r2W, sizeof(win2008r2W) ); + } + else if (ver->dwMajorVersion == 6 && ver->dwMinorVersion == 0) + { + if (ver->wProductType == VER_NT_WORKSTATION) memcpy( ret + len, vistaW, sizeof(vistaW) ); + else memcpy( ret + len, win2008W, sizeof(win2008W) ); + } + else if (ver->dwMajorVersion == 5 && ver->dwMinorVersion == 2) + { + if (ver->wProductType == VER_NT_WORKSTATION) memcpy( ret + len, winxp64W, sizeof(winxp64W) ); + else memcpy( ret + len, win2003W, sizeof(win2003W) ); + } + else if (ver->dwMajorVersion == 5 && ver->dwMinorVersion == 1) memcpy( ret + len, winxpW, sizeof(winxpW) ); + else memcpy( ret + len, win2000W, sizeof(win2000W) ); + return ret; +} +static WCHAR *get_osname( const WCHAR *caption ) +{ + static const WCHAR partitionW[] = + {'|','C',':','\\','W','I','N','D','O','W','S','|','\\','D','e','v','i','c','e','\\', + 'H','a','r','d','d','i','s','k','0','\\','P','a','r','t','i','t','i','o','n','1',0}; + int len = strlenW( caption ); + WCHAR *ret; + + if (!(ret = heap_alloc( len * sizeof(WCHAR) + sizeof(partitionW) ))) return NULL; + memcpy( ret, caption, len * sizeof(WCHAR) ); + memcpy( ret + len, partitionW, sizeof(partitionW) ); + return ret; +} +static WCHAR *get_osversion( OSVERSIONINFOEXW *ver ) +{ + static const WCHAR fmtW[] = {'%','u','.','%','u','.','%','u',0}; + WCHAR *ret = heap_alloc( 33 * sizeof(WCHAR) ); + if (ret) sprintfW( ret, fmtW, ver->dwMajorVersion, ver->dwMinorVersion, ver->dwBuildNumber ); + return ret; +} + +static enum fill_status fill_os( struct table *table, const struct expr *cond ) +{ + struct record_operatingsystem *rec; + enum fill_status status = FILL_STATUS_UNFILTERED; + OSVERSIONINFOEXW ver; + UINT row = 0; + + if (!resize_table( table, 1, sizeof(*rec) )) return FILL_STATUS_FAILED; + + ver.dwOSVersionInfoSize = sizeof(ver); + GetVersionExW( (OSVERSIONINFOW *)&ver ); + + rec = (struct record_operatingsystem *)table->data; + rec->buildnumber = get_osbuildnumber( &ver ); + rec->caption = get_oscaption( &ver ); + rec->codeset = get_codeset(); + rec->countrycode = get_countrycode(); + rec->csdversion = ver.szCSDVersion[0] ? heap_strdupW( ver.szCSDVersion ) : NULL; + rec->installdate = os_installdateW; + rec->lastbootuptime = get_lastbootuptime(); + rec->localdatetime = get_localdatetime(); + rec->locale = get_locale(); + rec->name = get_osname( rec->caption ); + rec->osarchitecture = get_osarchitecture(); + rec->oslanguage = GetSystemDefaultLangID(); + rec->osproductsuite = 2461140; /* Windows XP Professional */ + rec->ostype = 18; /* WINNT */ + rec->primary = -1; + rec->serialnumber = os_serialnumberW; + rec->servicepackmajor = ver.wServicePackMajor; + rec->servicepackminor = ver.wServicePackMinor; + rec->suitemask = 272; /* Single User + Terminal */ + rec->systemdirectory = get_systemdirectory(); + rec->totalvisiblememorysize = get_total_physical_memory() / 1024; + rec->version = get_osversion( &ver ); + if (!match_row( table, row, cond, &status )) free_row_values( table, row ); + else row++; + + TRACE("created %u rows\n", row); + table->num_rows = row; + return status; +} + +static const WCHAR *get_service_type( DWORD type ) +{ + static const WCHAR filesystem_driverW[] = + {'F','i','l','e',' ','S','y','s','t','e','m',' ','D','r','i','v','e','r',0}; + static const WCHAR kernel_driverW[] = + {'K','e','r','n','e','l',' ','D','r','i','v','e','r',0}; + static const WCHAR own_processW[] = + {'O','w','n',' ','P','r','o','c','e','s','s',0}; + static const WCHAR share_processW[] = + {'S','h','a','r','e',' ','P','r','o','c','e','s','s',0}; + + if (type & SERVICE_KERNEL_DRIVER) return kernel_driverW; + else if (type & SERVICE_FILE_SYSTEM_DRIVER) return filesystem_driverW; + else if (type & SERVICE_WIN32_OWN_PROCESS) return own_processW; + else if (type & SERVICE_WIN32_SHARE_PROCESS) return share_processW; + else ERR("unhandled type 0x%08x\n", type); + return NULL; +} +static const WCHAR *get_service_state( DWORD state ) +{ + static const WCHAR runningW[] = + {'R','u','n','n','i','n','g',0}; + static const WCHAR start_pendingW[] = + {'S','t','a','r','t',' ','P','e','n','d','i','n','g',0}; + static const WCHAR stop_pendingW[] = + {'S','t','o','p',' ','P','e','n','d','i','n','g',0}; + static const WCHAR stoppedW[] = + {'S','t','o','p','p','e','d',0}; + static const WCHAR unknownW[] = + {'U','n','k','n','o','w','n',0}; + + switch (state) + { + case SERVICE_STOPPED: return stoppedW; + case SERVICE_START_PENDING: return start_pendingW; + case SERVICE_STOP_PENDING: return stop_pendingW; + case SERVICE_RUNNING: return runningW; + default: + ERR("unknown state %u\n", state); + return unknownW; + } +} +static const WCHAR *get_service_startmode( DWORD mode ) +{ + static const WCHAR bootW[] = {'B','o','o','t',0}; + static const WCHAR systemW[] = {'S','y','s','t','e','m',0}; + static const WCHAR autoW[] = {'A','u','t','o',0}; + static const WCHAR manualW[] = {'M','a','n','u','a','l',0}; + static const WCHAR disabledW[] = {'D','i','s','a','b','l','e','d',0}; + static const WCHAR unknownW[] = {'U','n','k','n','o','w','n',0}; + + switch (mode) + { + case SERVICE_BOOT_START: return bootW; + case SERVICE_SYSTEM_START: return systemW; + case SERVICE_AUTO_START: return autoW; + case SERVICE_DEMAND_START: return manualW; + case SERVICE_DISABLED: return disabledW; + default: + ERR("unknown mode 0x%x\n", mode); + return unknownW; + } +} +static QUERY_SERVICE_CONFIGW *query_service_config( SC_HANDLE manager, const WCHAR *name ) +{ + QUERY_SERVICE_CONFIGW *config = NULL; + SC_HANDLE service; + DWORD size; + + if (!(service = OpenServiceW( manager, name, SERVICE_QUERY_CONFIG ))) return NULL; + QueryServiceConfigW( service, NULL, 0, &size ); + if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) goto done; + if (!(config = heap_alloc( size ))) goto done; + if (QueryServiceConfigW( service, config, size, &size )) goto done; + heap_free( config ); + config = NULL; + +done: + CloseServiceHandle( service ); + return config; +} + +static enum fill_status fill_service( struct table *table, const struct expr *cond ) +{ + struct record_service *rec; + SC_HANDLE manager; + ENUM_SERVICE_STATUS_PROCESSW *tmp, *services = NULL; + SERVICE_STATUS_PROCESS *status; + WCHAR sysnameW[MAX_COMPUTERNAME_LENGTH + 1]; + DWORD len = sizeof(sysnameW) / sizeof(sysnameW[0]); + UINT i, row = 0, offset = 0, size = 256, needed, count; + enum fill_status fill_status = FILL_STATUS_FAILED; + BOOL ret; + + if (!(manager = OpenSCManagerW( NULL, NULL, SC_MANAGER_ENUMERATE_SERVICE ))) return FILL_STATUS_FAILED; + if (!(services = heap_alloc( size ))) goto done; + + ret = EnumServicesStatusExW( manager, SC_ENUM_PROCESS_INFO, SERVICE_TYPE_ALL, + SERVICE_STATE_ALL, (BYTE *)services, size, &needed, + &count, NULL, NULL ); + if (!ret) + { + if (GetLastError() != ERROR_MORE_DATA) goto done; + size = needed; + if (!(tmp = heap_realloc( services, size ))) goto done; + services = tmp; + ret = EnumServicesStatusExW( manager, SC_ENUM_PROCESS_INFO, SERVICE_TYPE_ALL, + SERVICE_STATE_ALL, (BYTE *)services, size, &needed, + &count, NULL, NULL ); + if (!ret) goto done; + } + if (!resize_table( table, count, sizeof(*rec) )) goto done; + + GetComputerNameW( sysnameW, &len ); + fill_status = FILL_STATUS_UNFILTERED; + + for (i = 0; i < count; i++) + { + QUERY_SERVICE_CONFIGW *config; + + if (!(config = query_service_config( manager, services[i].lpServiceName ))) continue; + + status = &services[i].ServiceStatusProcess; + rec = (struct record_service *)(table->data + offset); + rec->accept_pause = (status->dwControlsAccepted & SERVICE_ACCEPT_PAUSE_CONTINUE) ? -1 : 0; + rec->accept_stop = (status->dwControlsAccepted & SERVICE_ACCEPT_STOP) ? -1 : 0; + rec->displayname = heap_strdupW( services[i].lpDisplayName ); + rec->name = heap_strdupW( services[i].lpServiceName ); + rec->process_id = status->dwProcessId; + rec->servicetype = get_service_type( status->dwServiceType ); + rec->startmode = get_service_startmode( config->dwStartType ); + rec->state = get_service_state( status->dwCurrentState ); + rec->systemname = heap_strdupW( sysnameW ); + rec->pause_service = service_pause_service; + rec->resume_service = service_resume_service; + rec->start_service = service_start_service; + rec->stop_service = service_stop_service; + heap_free( config ); + if (!match_row( table, row, cond, &fill_status )) + { + free_row_values( table, row ); + continue; + } + offset += sizeof(*rec); + row++; + } + + TRACE("created %u rows\n", row); + table->num_rows = row; + +done: + CloseServiceHandle( manager ); + heap_free( services ); + return fill_status; +} + +static WCHAR *get_accountname( LSA_TRANSLATED_NAME *name ) +{ + if (!name || !name->Name.Buffer) return NULL; + return heap_strdupW( name->Name.Buffer ); +} +static struct array *get_binaryrepresentation( PSID sid, UINT len ) +{ + struct array *array = heap_alloc( sizeof(struct array) ); + if (array) + { + UINT8 *ret = heap_alloc( len ); + if (ret) + { + memcpy( ret, sid, len ); + array->count = len; + array->ptr = ret; + return array; + } + heap_free( array ); + } + return NULL; +} +static WCHAR *get_referenceddomainname( LSA_REFERENCED_DOMAIN_LIST *domain ) +{ + if (!domain || !domain->Domains || !domain->Domains->Name.Buffer) return NULL; + return heap_strdupW( domain->Domains->Name.Buffer ); +} +static const WCHAR *find_sid_str( const struct expr *cond ) +{ + const struct expr *left, *right; + const WCHAR *ret = NULL; + + if (!cond || cond->type != EXPR_COMPLEX || cond->u.expr.op != OP_EQ) return NULL; + + left = cond->u.expr.left; + right = cond->u.expr.right; + if (left->type == EXPR_PROPVAL && right->type == EXPR_SVAL && !strcmpiW( left->u.propval->name, prop_sidW )) + { + ret = right->u.sval; + } + else if (left->type == EXPR_SVAL && right->type == EXPR_PROPVAL && !strcmpiW( right->u.propval->name, prop_sidW )) + { + ret = left->u.sval; + } + return ret; +} + +static enum fill_status fill_sid( struct table *table, const struct expr *cond ) +{ + PSID sid; + LSA_REFERENCED_DOMAIN_LIST *domain; + LSA_TRANSLATED_NAME *name; + LSA_HANDLE handle; + LSA_OBJECT_ATTRIBUTES attrs; + const WCHAR *str; + struct record_sid *rec; + UINT len; + + if (!(str = find_sid_str( cond ))) return FILL_STATUS_FAILED; + if (!resize_table( table, 1, sizeof(*rec) )) return FILL_STATUS_FAILED; + + if (!ConvertStringSidToSidW( str, &sid )) return FILL_STATUS_FAILED; + len = GetLengthSid( sid ); + + memset( &attrs, 0, sizeof(attrs) ); + attrs.Length = sizeof(attrs); + if (LsaOpenPolicy( NULL, &attrs, POLICY_ALL_ACCESS, &handle )) + { + LocalFree( sid ); + return FILL_STATUS_FAILED; + } + if (LsaLookupSids( handle, 1, &sid, &domain, &name )) + { + LocalFree( sid ); + LsaClose( handle ); + return FILL_STATUS_FAILED; + } + + rec = (struct record_sid *)table->data; + rec->accountname = get_accountname( name ); + rec->binaryrepresentation = get_binaryrepresentation( sid, len ); + rec->referenceddomainname = get_referenceddomainname( domain ); + rec->sid = heap_strdupW( str ); + rec->sidlength = len; + + TRACE("created 1 row\n"); + table->num_rows = 1; + + LsaFreeMemory( domain ); + LsaFreeMemory( name ); + LocalFree( sid ); + LsaClose( handle ); + return FILL_STATUS_FILTERED; +} + +#ifndef __REACTOS__ + +static UINT32 get_bits_per_pixel( UINT *hres, UINT *vres ) +{ + HDC hdc = GetDC( NULL ); + UINT32 ret; + + if (!hdc) return 32; + ret = GetDeviceCaps( hdc, BITSPIXEL ); + *hres = GetDeviceCaps( hdc, HORZRES ); + *vres = GetDeviceCaps( hdc, VERTRES ); + ReleaseDC( NULL, hdc ); + return ret; +} +static WCHAR *get_pnpdeviceid( DXGI_ADAPTER_DESC *desc ) +{ + static const WCHAR fmtW[] = + {'P','C','I','\\','V','E','N','_','%','0','4','X','&','D','E','V','_','%','0','4','X', + '&','S','U','B','S','Y','S','_','%','0','8','X','&','R','E','V','_','%','0','2','X','\\', + '0','&','D','E','A','D','B','E','E','F','&','0','&','D','E','A','D',0}; + WCHAR *ret; + + if (!(ret = heap_alloc( sizeof(fmtW) + 2 * sizeof(WCHAR) ))) return NULL; + sprintfW( ret, fmtW, desc->VendorId, desc->DeviceId, desc->SubSysId, desc->Revision ); + return ret; +} + +static enum fill_status fill_videocontroller( struct table *table, const struct expr *cond ) +{ + static const WCHAR fmtW[] = {'%','u',' ','x',' ','%','u',' ','x',' ','%','I','6','4','u',' ','c','o','l','o','r','s',0}; + struct record_videocontroller *rec; + HRESULT hr; + IDXGIFactory *factory = NULL; + IDXGIAdapter *adapter = NULL; + DXGI_ADAPTER_DESC desc; + UINT row = 0, hres = 1024, vres = 768, vidmem = 512 * 1024 * 1024; + const WCHAR *name = videocontroller_deviceidW; + enum fill_status status = FILL_STATUS_UNFILTERED; + WCHAR mode[44]; + + if (!resize_table( table, 1, sizeof(*rec) )) return FILL_STATUS_FAILED; + + memset (&desc, 0, sizeof(desc)); + hr = CreateDXGIFactory( &IID_IDXGIFactory, (void **)&factory ); + if (FAILED(hr)) goto done; + + hr = IDXGIFactory_EnumAdapters( factory, 0, &adapter ); + if (FAILED(hr)) goto done; + + hr = IDXGIAdapter_GetDesc( adapter, &desc ); + if (SUCCEEDED(hr)) + { + vidmem = desc.DedicatedVideoMemory; + name = desc.Description; + } + +done: + rec = (struct record_videocontroller *)table->data; + rec->adapter_dactype = videocontroller_dactypeW; + rec->adapter_ram = vidmem; + rec->availability = 3; /* Running or Full Power */ + rec->caption = heap_strdupW( name ); + rec->current_bitsperpixel = get_bits_per_pixel( &hres, &vres ); + rec->current_horizontalres = hres; + rec->current_refreshrate = 0; /* default refresh rate */ + rec->current_scanmode = 2; /* Unknown */ + rec->current_verticalres = vres; + rec->description = heap_strdupW( name ); + rec->device_id = videocontroller_deviceidW; + rec->driverversion = videocontroller_driverversionW; + rec->name = heap_strdupW( name ); + rec->pnpdevice_id = get_pnpdeviceid( &desc ); + rec->videoarchitecture = 2; /* Unknown */ + rec->videomemorytype = 2; /* Unknown */ + wsprintfW( mode, fmtW, hres, vres, (UINT64)1 << rec->current_bitsperpixel ); + rec->videomodedescription = heap_strdupW( mode ); + rec->videoprocessor = heap_strdupW( name ); + if (!match_row( table, row, cond, &status )) free_row_values( table, row ); + else row++; + + TRACE("created %u rows\n", row); + table->num_rows = row; + + if (adapter) IDXGIAdapter_Release( adapter ); + if (factory) IDXGIFactory_Release( factory ); + return status; +} + +#endif /* !__REACTOS__ */ + +static struct table builtin_classes[] = +{ + { class_baseboardW, SIZEOF(col_baseboard), col_baseboard, SIZEOF(data_baseboard), 0, (BYTE *)data_baseboard }, + { class_biosW, SIZEOF(col_bios), col_bios, SIZEOF(data_bios), 0, (BYTE *)data_bios }, + { class_cdromdriveW, SIZEOF(col_cdromdrive), col_cdromdrive, 0, 0, NULL, fill_cdromdrive }, + { class_compsysW, SIZEOF(col_compsys), col_compsys, 0, 0, NULL, fill_compsys }, + { class_compsysproductW, SIZEOF(col_compsysproduct), col_compsysproduct, 0, 0, NULL, fill_compsysproduct }, + { class_datafileW, SIZEOF(col_datafile), col_datafile, 0, 0, NULL, fill_datafile }, + { class_desktopmonitorW, SIZEOF(col_desktopmonitor), col_desktopmonitor, 0, 0, NULL, fill_desktopmonitor }, + { class_directoryW, SIZEOF(col_directory), col_directory, 0, 0, NULL, fill_directory }, + { class_diskdriveW, SIZEOF(col_diskdrive), col_diskdrive, 0, 0, NULL, fill_diskdrive }, + { class_diskpartitionW, SIZEOF(col_diskpartition), col_diskpartition, 0, 0, NULL, fill_diskpartition }, + { class_logicaldiskW, SIZEOF(col_logicaldisk), col_logicaldisk, 0, 0, NULL, fill_logicaldisk }, + { class_logicaldisk2W, SIZEOF(col_logicaldisk), col_logicaldisk, 0, 0, NULL, fill_logicaldisk }, + { class_networkadapterW, SIZEOF(col_networkadapter), col_networkadapter, 0, 0, NULL, fill_networkadapter }, + { class_networkadapterconfigW, SIZEOF(col_networkadapterconfig), col_networkadapterconfig, 0, 0, NULL, fill_networkadapterconfig }, + { class_osW, SIZEOF(col_os), col_os, 0, 0, NULL, fill_os }, + { class_paramsW, SIZEOF(col_param), col_param, SIZEOF(data_param), 0, (BYTE *)data_param }, + { class_physicalmediaW, SIZEOF(col_physicalmedia), col_physicalmedia, SIZEOF(data_physicalmedia), 0, (BYTE *)data_physicalmedia }, + { class_physicalmemoryW, SIZEOF(col_physicalmemory), col_physicalmemory, 0, 0, NULL, fill_physicalmemory }, + { class_printerW, SIZEOF(col_printer), col_printer, 0, 0, NULL, fill_printer }, + { class_processW, SIZEOF(col_process), col_process, 0, 0, NULL, fill_process }, + { class_processorW, SIZEOF(col_processor), col_processor, 0, 0, NULL, fill_processor }, + { class_processor2W, SIZEOF(col_processor), col_processor, 0, 0, NULL, fill_processor }, + { class_qualifiersW, SIZEOF(col_qualifier), col_qualifier, SIZEOF(data_qualifier), 0, (BYTE *)data_qualifier }, + { class_serviceW, SIZEOF(col_service), col_service, 0, 0, NULL, fill_service }, + { class_sidW, SIZEOF(col_sid), col_sid, 0, 0, NULL, fill_sid }, + { class_sounddeviceW, SIZEOF(col_sounddevice), col_sounddevice, SIZEOF(data_sounddevice), 0, (BYTE *)data_sounddevice }, + { class_stdregprovW, SIZEOF(col_stdregprov), col_stdregprov, SIZEOF(data_stdregprov), 0, (BYTE *)data_stdregprov }, + { class_systemsecurityW, SIZEOF(col_systemsecurity), col_systemsecurity, SIZEOF(data_systemsecurity), 0, (BYTE *)data_systemsecurity }, + { class_systemenclosureW, SIZEOF(col_systemenclosure), col_systemenclosure, SIZEOF(data_systemenclosure), 0, (BYTE *)data_systemenclosure }, +#ifndef __REACTOS__ + /* Requires dxgi.dll */ + { class_videocontrollerW, SIZEOF(col_videocontroller), col_videocontroller, 0, 0, NULL, fill_videocontroller } +#endif +}; + +void init_table_list( void ) +{ + static struct list tables = LIST_INIT( tables ); + UINT i; + + for (i = 0; i < SIZEOF(builtin_classes); i++) list_add_tail( &tables, &builtin_classes[i].entry ); + table_list = &tables; +} diff --git a/reactos/dll/win32/wbemprox/class.c b/reactos/dll/win32/wbemprox/class.c new file mode 100644 index 00000000000..3d3e777861c --- /dev/null +++ b/reactos/dll/win32/wbemprox/class.c @@ -0,0 +1,1030 @@ +/* + * Copyright 2012 Hans Leidekker for CodeWeavers + * + * 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 "wbemprox_private.h" + +struct enum_class_object +{ + IEnumWbemClassObject IEnumWbemClassObject_iface; + LONG refs; + struct query *query; + UINT index; +}; + +static inline struct enum_class_object *impl_from_IEnumWbemClassObject( + IEnumWbemClassObject *iface ) +{ + return CONTAINING_RECORD(iface, struct enum_class_object, IEnumWbemClassObject_iface); +} + +static ULONG WINAPI enum_class_object_AddRef( + IEnumWbemClassObject *iface ) +{ + struct enum_class_object *ec = impl_from_IEnumWbemClassObject( iface ); + return InterlockedIncrement( &ec->refs ); +} + +static ULONG WINAPI enum_class_object_Release( + IEnumWbemClassObject *iface ) +{ + struct enum_class_object *ec = impl_from_IEnumWbemClassObject( iface ); + LONG refs = InterlockedDecrement( &ec->refs ); + if (!refs) + { + TRACE("destroying %p\n", ec); + release_query( ec->query ); + heap_free( ec ); + } + return refs; +} + +static HRESULT WINAPI enum_class_object_QueryInterface( + IEnumWbemClassObject *iface, + REFIID riid, + void **ppvObject ) +{ + struct enum_class_object *ec = impl_from_IEnumWbemClassObject( iface ); + + TRACE("%p, %s, %p\n", ec, debugstr_guid( riid ), ppvObject ); + + if ( IsEqualGUID( riid, &IID_IEnumWbemClassObject ) || + IsEqualGUID( riid, &IID_IUnknown ) ) + { + *ppvObject = ec; + } + else if ( IsEqualGUID( riid, &IID_IClientSecurity ) ) + { + *ppvObject = &client_security; + return S_OK; + } + else + { + FIXME("interface %s not implemented\n", debugstr_guid(riid)); + return E_NOINTERFACE; + } + IEnumWbemClassObject_AddRef( iface ); + return S_OK; +} + +static HRESULT WINAPI enum_class_object_Reset( + IEnumWbemClassObject *iface ) +{ + struct enum_class_object *ec = impl_from_IEnumWbemClassObject( iface ); + + TRACE("%p\n", iface); + + ec->index = 0; + return WBEM_S_NO_ERROR; +} + +static HRESULT WINAPI enum_class_object_Next( + IEnumWbemClassObject *iface, + LONG lTimeout, + ULONG uCount, + IWbemClassObject **apObjects, + ULONG *puReturned ) +{ + struct enum_class_object *ec = impl_from_IEnumWbemClassObject( iface ); + struct view *view = ec->query->view; + static int once = 0; + HRESULT hr; + + TRACE("%p, %d, %u, %p, %p\n", iface, lTimeout, uCount, apObjects, puReturned); + + if (!uCount) return WBEM_S_FALSE; + if (!apObjects || !puReturned) return WBEM_E_INVALID_PARAMETER; + if (lTimeout != WBEM_INFINITE && !once++) FIXME("timeout not supported\n"); + + *puReturned = 0; + if (ec->index >= view->count) return WBEM_S_FALSE; + + hr = create_class_object( view->table->name, iface, ec->index, NULL, apObjects ); + if (hr != S_OK) return hr; + + ec->index++; + *puReturned = 1; + if (ec->index == view->count && uCount > 1) return WBEM_S_FALSE; + if (uCount > 1) return WBEM_S_TIMEDOUT; + return WBEM_S_NO_ERROR; +} + +static HRESULT WINAPI enum_class_object_NextAsync( + IEnumWbemClassObject *iface, + ULONG uCount, + IWbemObjectSink *pSink ) +{ + FIXME("%p, %u, %p\n", iface, uCount, pSink); + return E_NOTIMPL; +} + +static HRESULT WINAPI enum_class_object_Clone( + IEnumWbemClassObject *iface, + IEnumWbemClassObject **ppEnum ) +{ + struct enum_class_object *ec = impl_from_IEnumWbemClassObject( iface ); + + TRACE("%p, %p\n", iface, ppEnum); + + return EnumWbemClassObject_create( ec->query, (void **)ppEnum ); +} + +static HRESULT WINAPI enum_class_object_Skip( + IEnumWbemClassObject *iface, + LONG lTimeout, + ULONG nCount ) +{ + struct enum_class_object *ec = impl_from_IEnumWbemClassObject( iface ); + struct view *view = ec->query->view; + static int once = 0; + + TRACE("%p, %d, %u\n", iface, lTimeout, nCount); + + if (lTimeout != WBEM_INFINITE && !once++) FIXME("timeout not supported\n"); + + if (!view->count) return WBEM_S_FALSE; + + if (nCount > view->count - ec->index) + { + ec->index = view->count - 1; + return WBEM_S_FALSE; + } + ec->index += nCount; + return WBEM_S_NO_ERROR; +} + +static const IEnumWbemClassObjectVtbl enum_class_object_vtbl = +{ + enum_class_object_QueryInterface, + enum_class_object_AddRef, + enum_class_object_Release, + enum_class_object_Reset, + enum_class_object_Next, + enum_class_object_NextAsync, + enum_class_object_Clone, + enum_class_object_Skip +}; + +HRESULT EnumWbemClassObject_create( struct query *query, LPVOID *ppObj ) +{ + struct enum_class_object *ec; + + TRACE("%p\n", ppObj); + + ec = heap_alloc( sizeof(*ec) ); + if (!ec) return E_OUTOFMEMORY; + + ec->IEnumWbemClassObject_iface.lpVtbl = &enum_class_object_vtbl; + ec->refs = 1; + ec->query = addref_query( query ); + ec->index = 0; + + *ppObj = &ec->IEnumWbemClassObject_iface; + + TRACE("returning iface %p\n", *ppObj); + return S_OK; +} + +static struct record *create_record( struct table *table ) +{ + UINT i; + struct record *record; + + if (!(record = heap_alloc( sizeof(struct record) ))) return NULL; + if (!(record->fields = heap_alloc( table->num_cols * sizeof(struct field) ))) + { + heap_free( record ); + return NULL; + } + for (i = 0; i < table->num_cols; i++) + { + record->fields[i].type = table->columns[i].type; + record->fields[i].vartype = table->columns[i].vartype; + record->fields[i].u.ival = 0; + } + record->count = table->num_cols; + record->table = addref_table( table ); + return record; +} + +void destroy_array( struct array *array, CIMTYPE type ) +{ + UINT i, size; + + if (!array) return; + if (type == CIM_STRING || type == CIM_DATETIME) + { + size = get_type_size( type ); + for (i = 0; i < array->count; i++) heap_free( *(WCHAR **)((char *)array->ptr + i * size) ); + } + heap_free( array->ptr ); + heap_free( array ); +} + +static void destroy_record( struct record *record ) +{ + UINT i; + + if (!record) return; + release_table( record->table ); + for (i = 0; i < record->count; i++) + { + if (record->fields[i].type == CIM_STRING || record->fields[i].type == CIM_DATETIME) + heap_free( record->fields[i].u.sval ); + else if (record->fields[i].type & CIM_FLAG_ARRAY) + destroy_array( record->fields[i].u.aval, record->fields[i].type & CIM_TYPE_MASK ); + } + heap_free( record->fields ); + heap_free( record ); +} + +struct class_object +{ + IWbemClassObject IWbemClassObject_iface; + LONG refs; + WCHAR *name; + IEnumWbemClassObject *iter; + UINT index; + UINT index_method; + UINT index_property; + struct record *record; /* uncommitted instance */ +}; + +static inline struct class_object *impl_from_IWbemClassObject( + IWbemClassObject *iface ) +{ + return CONTAINING_RECORD(iface, struct class_object, IWbemClassObject_iface); +} + +static ULONG WINAPI class_object_AddRef( + IWbemClassObject *iface ) +{ + struct class_object *co = impl_from_IWbemClassObject( iface ); + return InterlockedIncrement( &co->refs ); +} + +static ULONG WINAPI class_object_Release( + IWbemClassObject *iface ) +{ + struct class_object *co = impl_from_IWbemClassObject( iface ); + LONG refs = InterlockedDecrement( &co->refs ); + if (!refs) + { + TRACE("destroying %p\n", co); + if (co->iter) IEnumWbemClassObject_Release( co->iter ); + destroy_record( co->record ); + heap_free( co->name ); + heap_free( co ); + } + return refs; +} + +static HRESULT WINAPI class_object_QueryInterface( + IWbemClassObject *iface, + REFIID riid, + void **ppvObject ) +{ + struct class_object *co = impl_from_IWbemClassObject( iface ); + + TRACE("%p, %s, %p\n", co, debugstr_guid( riid ), ppvObject ); + + if ( IsEqualGUID( riid, &IID_IWbemClassObject ) || + IsEqualGUID( riid, &IID_IUnknown ) ) + { + *ppvObject = co; + } + else if (IsEqualGUID( riid, &IID_IClientSecurity )) + { + *ppvObject = &client_security; + return S_OK; + } + else + { + FIXME("interface %s not implemented\n", debugstr_guid(riid)); + return E_NOINTERFACE; + } + IWbemClassObject_AddRef( iface ); + return S_OK; +} + +static HRESULT WINAPI class_object_GetQualifierSet( + IWbemClassObject *iface, + IWbemQualifierSet **ppQualSet ) +{ + FIXME("%p, %p\n", iface, ppQualSet); + return E_NOTIMPL; +} + +static HRESULT record_get_value( const struct record *record, UINT index, VARIANT *var, CIMTYPE *type ) +{ + VARTYPE vartype = record->fields[index].vartype; + + if (type) *type = record->fields[index].type; + + if (record->fields[index].type & CIM_FLAG_ARRAY) + { + V_VT( var ) = vartype ? vartype : to_vartype( record->fields[index].type & CIM_TYPE_MASK ) | VT_ARRAY; + V_ARRAY( var ) = to_safearray( record->fields[index].u.aval, record->fields[index].type & CIM_TYPE_MASK ); + return S_OK; + } + switch (record->fields[index].type) + { + case CIM_STRING: + case CIM_DATETIME: + if (!vartype) vartype = VT_BSTR; + V_BSTR( var ) = SysAllocString( record->fields[index].u.sval ); + break; + case CIM_SINT32: + if (!vartype) vartype = VT_I4; + V_I4( var ) = record->fields[index].u.ival; + break; + case CIM_UINT32: + if (!vartype) vartype = VT_UI4; + V_UI4( var ) = record->fields[index].u.ival; + break; + default: + FIXME("unhandled type %u\n", record->fields[index].type); + return WBEM_E_INVALID_PARAMETER; + } + V_VT( var ) = vartype; + return S_OK; +} + +static HRESULT WINAPI class_object_Get( + IWbemClassObject *iface, + LPCWSTR wszName, + LONG lFlags, + VARIANT *pVal, + CIMTYPE *pType, + LONG *plFlavor ) +{ + struct class_object *co = impl_from_IWbemClassObject( iface ); + struct enum_class_object *ec = impl_from_IEnumWbemClassObject( co->iter ); + + TRACE("%p, %s, %08x, %p, %p, %p\n", iface, debugstr_w(wszName), lFlags, pVal, pType, plFlavor); + + if (co->record) + { + UINT index; + HRESULT hr; + + if ((hr = get_column_index( co->record->table, wszName, &index )) != S_OK) return hr; + return record_get_value( co->record, index, pVal, pType ); + } + return get_propval( ec->query->view, co->index, wszName, pVal, pType, plFlavor ); +} + +static HRESULT record_set_value( struct record *record, UINT index, VARIANT *var ) +{ + LONGLONG val; + CIMTYPE type; + HRESULT hr; + + if ((hr = to_longlong( var, &val, &type )) != S_OK) return hr; + if (type != record->fields[index].type) return WBEM_E_TYPE_MISMATCH; + + if (type & CIM_FLAG_ARRAY) + { + record->fields[index].u.aval = (struct array *)(INT_PTR)val; + return S_OK; + } + switch (type) + { + case CIM_STRING: + case CIM_DATETIME: + record->fields[index].u.sval = (WCHAR *)(INT_PTR)val; + return S_OK; + case CIM_SINT16: + case CIM_UINT16: + case CIM_SINT32: + case CIM_UINT32: + record->fields[index].u.ival = val; + return S_OK; + default: + FIXME("unhandled type %u\n", type); + break; + } + return WBEM_E_INVALID_PARAMETER; +} + +static HRESULT WINAPI class_object_Put( + IWbemClassObject *iface, + LPCWSTR wszName, + LONG lFlags, + VARIANT *pVal, + CIMTYPE Type ) +{ + struct class_object *co = impl_from_IWbemClassObject( iface ); + struct enum_class_object *ec = impl_from_IEnumWbemClassObject( co->iter ); + + TRACE("%p, %s, %08x, %p, %u\n", iface, debugstr_w(wszName), lFlags, pVal, Type); + + if (co->record) + { + UINT index; + HRESULT hr; + + if ((hr = get_column_index( co->record->table, wszName, &index )) != S_OK) return hr; + return record_set_value( co->record, index, pVal ); + } + return put_propval( ec->query->view, co->index, wszName, pVal, Type ); +} + +static HRESULT WINAPI class_object_Delete( + IWbemClassObject *iface, + LPCWSTR wszName ) +{ + FIXME("%p, %s\n", iface, debugstr_w(wszName)); + return E_NOTIMPL; +} + +static HRESULT WINAPI class_object_GetNames( + IWbemClassObject *iface, + LPCWSTR wszQualifierName, + LONG lFlags, + VARIANT *pQualifierVal, + SAFEARRAY **pNames ) +{ + struct class_object *co = impl_from_IWbemClassObject( iface ); + struct enum_class_object *ec = impl_from_IEnumWbemClassObject( co->iter ); + + TRACE("%p, %s, %08x, %s, %p\n", iface, debugstr_w(wszQualifierName), lFlags, + debugstr_variant(pQualifierVal), pNames); + + if (lFlags != WBEM_FLAG_ALWAYS && + lFlags != WBEM_FLAG_NONSYSTEM_ONLY && + lFlags != WBEM_FLAG_SYSTEM_ONLY) + { + FIXME("flags %08x not supported\n", lFlags); + return E_NOTIMPL; + } + if (wszQualifierName || pQualifierVal) + FIXME("qualifier not supported\n"); + + return get_properties( ec->query->view, lFlags, pNames ); +} + +static HRESULT WINAPI class_object_BeginEnumeration( + IWbemClassObject *iface, + LONG lEnumFlags ) +{ + struct class_object *co = impl_from_IWbemClassObject( iface ); + + TRACE("%p, %08x\n", iface, lEnumFlags); + + if (lEnumFlags) FIXME("flags 0x%08x not supported\n", lEnumFlags); + + co->index_property = 0; + return S_OK; +} + +static HRESULT WINAPI class_object_Next( + IWbemClassObject *iface, + LONG lFlags, + BSTR *strName, + VARIANT *pVal, + CIMTYPE *pType, + LONG *plFlavor ) +{ + struct class_object *obj = impl_from_IWbemClassObject( iface ); + struct enum_class_object *iter = impl_from_IEnumWbemClassObject( obj->iter ); + struct view *view = iter->query->view; + BSTR prop; + HRESULT hr; + UINT i; + + TRACE("%p, %08x, %p, %p, %p, %p\n", iface, lFlags, strName, pVal, pType, plFlavor); + + for (i = obj->index_property; i < view->table->num_cols; i++) + { + if (is_method( view->table, i )) continue; + if (!is_selected_prop( view, view->table->columns[i].name )) continue; + if (!(prop = SysAllocString( view->table->columns[i].name ))) return E_OUTOFMEMORY; + if ((hr = get_propval( view, obj->index, prop, pVal, pType, plFlavor )) != S_OK) + { + SysFreeString( prop ); + return hr; + } + obj->index_property = i + 1; + *strName = prop; + return S_OK; + } + return WBEM_S_NO_MORE_DATA; +} + +static HRESULT WINAPI class_object_EndEnumeration( + IWbemClassObject *iface ) +{ + struct class_object *co = impl_from_IWbemClassObject( iface ); + + TRACE("%p\n", iface); + + co->index_property = 0; + return S_OK; +} + +static HRESULT WINAPI class_object_GetPropertyQualifierSet( + IWbemClassObject *iface, + LPCWSTR wszProperty, + IWbemQualifierSet **ppQualSet ) +{ + struct class_object *co = impl_from_IWbemClassObject( iface ); + + TRACE("%p, %s, %p\n", iface, debugstr_w(wszProperty), ppQualSet); + + return WbemQualifierSet_create( co->name, wszProperty, (void **)ppQualSet ); +} + +static HRESULT WINAPI class_object_Clone( + IWbemClassObject *iface, + IWbemClassObject **ppCopy ) +{ + FIXME("%p, %p\n", iface, ppCopy); + return E_NOTIMPL; +} + +static BSTR get_body_text( const struct table *table, UINT row, UINT *len ) +{ + static const WCHAR fmtW[] = {'\n','\t','%','s',' ','=',' ','%','s',';',0}; + BSTR value, ret; + WCHAR *p; + UINT i; + + *len = 0; + for (i = 0; i < table->num_cols; i++) + { + if ((value = get_value_bstr( table, row, i ))) + { + *len += sizeof(fmtW) / sizeof(fmtW[0]); + *len += strlenW( table->columns[i].name ); + *len += SysStringLen( value ); + SysFreeString( value ); + } + } + if (!(ret = SysAllocStringLen( NULL, *len ))) return NULL; + p = ret; + for (i = 0; i < table->num_cols; i++) + { + if ((value = get_value_bstr( table, row, i ))) + { + p += sprintfW( p, fmtW, table->columns[i].name, value ); + SysFreeString( value ); + } + } + return ret; +} + +static BSTR get_object_text( const struct view *view, UINT index ) +{ + static const WCHAR fmtW[] = + {'\n','i','n','s','t','a','n','c','e',' ','o','f',' ','%','s','\n','{','%','s','\n','}',';',0}; + UINT len, len_body, row = view->result[index]; + BSTR ret, body; + + len = sizeof(fmtW) / sizeof(fmtW[0]); + len += strlenW( view->table->name ); + if (!(body = get_body_text( view->table, row, &len_body ))) return NULL; + len += len_body; + + if (!(ret = SysAllocStringLen( NULL, len ))) return NULL; + sprintfW( ret, fmtW, view->table->name, body ); + SysFreeString( body ); + return ret; +} + +static HRESULT WINAPI class_object_GetObjectText( + IWbemClassObject *iface, + LONG lFlags, + BSTR *pstrObjectText ) +{ + struct class_object *co = impl_from_IWbemClassObject( iface ); + struct enum_class_object *ec = impl_from_IEnumWbemClassObject( co->iter ); + struct view *view = ec->query->view; + BSTR text; + + TRACE("%p, %08x, %p\n", iface, lFlags, pstrObjectText); + + if (lFlags) FIXME("flags %08x not implemented\n", lFlags); + + if (!(text = get_object_text( view, co->index ))) return E_OUTOFMEMORY; + *pstrObjectText = text; + return S_OK; +} + +static HRESULT WINAPI class_object_SpawnDerivedClass( + IWbemClassObject *iface, + LONG lFlags, + IWbemClassObject **ppNewClass ) +{ + FIXME("%p, %08x, %p\n", iface, lFlags, ppNewClass); + return E_NOTIMPL; +} + +static HRESULT WINAPI class_object_SpawnInstance( + IWbemClassObject *iface, + LONG lFlags, + IWbemClassObject **ppNewInstance ) +{ + struct class_object *co = impl_from_IWbemClassObject( iface ); + struct enum_class_object *ec = impl_from_IEnumWbemClassObject( co->iter ); + struct view *view = ec->query->view; + struct record *record; + + TRACE("%p, %08x, %p\n", iface, lFlags, ppNewInstance); + + if (!(record = create_record( view->table ))) return E_OUTOFMEMORY; + + return create_class_object( co->name, NULL, 0, record, ppNewInstance ); +} + +static HRESULT WINAPI class_object_CompareTo( + IWbemClassObject *iface, + LONG lFlags, + IWbemClassObject *pCompareTo ) +{ + FIXME("%p, %08x, %p\n", iface, lFlags, pCompareTo); + return E_NOTIMPL; +} + +static HRESULT WINAPI class_object_GetPropertyOrigin( + IWbemClassObject *iface, + LPCWSTR wszName, + BSTR *pstrClassName ) +{ + FIXME("%p, %s, %p\n", iface, debugstr_w(wszName), pstrClassName); + return E_NOTIMPL; +} + +static HRESULT WINAPI class_object_InheritsFrom( + IWbemClassObject *iface, + LPCWSTR strAncestor ) +{ + FIXME("%p, %s\n", iface, debugstr_w(strAncestor)); + return E_NOTIMPL; +} + +static UINT count_instances( IEnumWbemClassObject *iter ) +{ + UINT count = 0; + while (!IEnumWbemClassObject_Skip( iter, WBEM_INFINITE, 1 )) count++; + IEnumWbemClassObject_Reset( iter ); + return count; +} + +static void set_default_value( CIMTYPE type, UINT val, BYTE *ptr ) +{ + switch (type) + { + case CIM_SINT16: + *(INT16 *)ptr = val; + break; + case CIM_UINT16: + *(UINT16 *)ptr = val; + break; + case CIM_SINT32: + *(INT32 *)ptr = val; + break; + case CIM_UINT32: + *(UINT32 *)ptr = val; + break; + default: + FIXME("unhandled type %u\n", type); + break; + } +} + +static HRESULT create_signature_columns_and_data( IEnumWbemClassObject *iter, UINT *num_cols, + struct column **cols, BYTE **data ) +{ + static const WCHAR parameterW[] = {'P','a','r','a','m','e','t','e','r',0}; + static const WCHAR typeW[] = {'T','y','p','e',0}; + static const WCHAR varianttypeW[] = {'V','a','r','i','a','n','t','T','y','p','e',0}; + static const WCHAR defaultvalueW[] = {'D','e','f','a','u','l','t','V','a','l','u','e',0}; + struct column *columns; + BYTE *row; + IWbemClassObject *param; + VARIANT val; + HRESULT hr = E_OUTOFMEMORY; + UINT offset = 0; + ULONG count; + int i = 0; + + count = count_instances( iter ); + if (!(columns = heap_alloc( count * sizeof(struct column) ))) return E_OUTOFMEMORY; + if (!(row = heap_alloc_zero( count * sizeof(LONGLONG) ))) goto error; + + for (;;) + { + IEnumWbemClassObject_Next( iter, WBEM_INFINITE, 1, ¶m, &count ); + if (!count) break; + + hr = IWbemClassObject_Get( param, parameterW, 0, &val, NULL, NULL ); + if (hr != S_OK) goto error; + columns[i].name = heap_strdupW( V_BSTR( &val ) ); + VariantClear( &val ); + + hr = IWbemClassObject_Get( param, typeW, 0, &val, NULL, NULL ); + if (hr != S_OK) goto error; + columns[i].type = V_UI4( &val ); + + hr = IWbemClassObject_Get( param, varianttypeW, 0, &val, NULL, NULL ); + if (hr != S_OK) goto error; + columns[i].vartype = V_UI4( &val ); + + hr = IWbemClassObject_Get( param, defaultvalueW, 0, &val, NULL, NULL ); + if (hr != S_OK) goto error; + if (V_UI4( &val )) set_default_value( columns[i].type, V_UI4( &val ), row + offset ); + offset += get_type_size( columns[i].type ); + + IWbemClassObject_Release( param ); + i++; + } + *num_cols = i; + *cols = columns; + *data = row; + return S_OK; + +error: + for (; i >= 0; i--) heap_free( (WCHAR *)columns[i].name ); + heap_free( columns ); + heap_free( row ); + return hr; +} + +static HRESULT create_signature_table( IEnumWbemClassObject *iter, WCHAR *name ) +{ + HRESULT hr; + struct table *table; + struct column *columns; + UINT num_cols; + BYTE *row; + + hr = create_signature_columns_and_data( iter, &num_cols, &columns, &row ); + if (hr != S_OK) return hr; + + if (!(table = create_table( name, num_cols, columns, 1, 1, row, NULL ))) + { + free_columns( columns, num_cols ); + heap_free( row ); + return E_OUTOFMEMORY; + } + if (!add_table( table )) free_table( table ); /* already exists */ + return S_OK; +} + +static WCHAR *build_signature_table_name( const WCHAR *class, const WCHAR *method, enum param_direction dir ) +{ + static const WCHAR fmtW[] = {'_','_','%','s','_','%','s','_','%','s',0}; + static const WCHAR outW[] = {'O','U','T',0}; + static const WCHAR inW[] = {'I','N',0}; + UINT len = SIZEOF(fmtW) + SIZEOF(outW) + strlenW( class ) + strlenW( method ); + WCHAR *ret; + + if (!(ret = heap_alloc( len * sizeof(WCHAR) ))) return NULL; + sprintfW( ret, fmtW, class, method, dir == PARAM_IN ? inW : outW ); + return struprW( ret ); +} + +HRESULT create_signature( const WCHAR *class, const WCHAR *method, enum param_direction dir, + IWbemClassObject **sig ) +{ + static const WCHAR selectW[] = + {'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ', + '_','_','P','A','R','A','M','E','T','E','R','S',' ','W','H','E','R','E',' ', + 'C','l','a','s','s','=','\'','%','s','\'',' ','A','N','D',' ', + 'M','e','t','h','o','d','=','\'','%','s','\'',' ','A','N','D',' ', + 'D','i','r','e','c','t','i','o','n','%','s',0}; + static const WCHAR geW[] = {'>','=','0',0}; + static const WCHAR leW[] = {'<','=','0',0}; + UINT len = SIZEOF(selectW) + SIZEOF(geW); + IEnumWbemClassObject *iter; + WCHAR *query, *name; + HRESULT hr; + + len += strlenW( class ) + strlenW( method ); + if (!(query = heap_alloc( len * sizeof(WCHAR) ))) return E_OUTOFMEMORY; + sprintfW( query, selectW, class, method, dir >= 0 ? geW : leW ); + + hr = exec_query( query, &iter ); + heap_free( query ); + if (hr != S_OK) return hr; + + if (!(name = build_signature_table_name( class, method, dir ))) + { + IEnumWbemClassObject_Release( iter ); + return E_OUTOFMEMORY; + } + hr = create_signature_table( iter, name ); + IEnumWbemClassObject_Release( iter ); + if (hr == S_OK) + hr = get_object( name, sig ); + + heap_free( name ); + return hr; +} + +static HRESULT WINAPI class_object_GetMethod( + IWbemClassObject *iface, + LPCWSTR wszName, + LONG lFlags, + IWbemClassObject **ppInSignature, + IWbemClassObject **ppOutSignature ) +{ + struct class_object *co = impl_from_IWbemClassObject( iface ); + IWbemClassObject *in, *out; + HRESULT hr; + + TRACE("%p, %s, %08x, %p, %p\n", iface, debugstr_w(wszName), lFlags, ppInSignature, ppOutSignature); + + hr = create_signature( co->name, wszName, PARAM_IN, &in ); + if (hr != S_OK) return hr; + + hr = create_signature( co->name, wszName, PARAM_OUT, &out ); + if (hr == S_OK) + { + if (ppInSignature) *ppInSignature = in; + else IWbemClassObject_Release( in ); + if (ppOutSignature) *ppOutSignature = out; + else IWbemClassObject_Release( out ); + } + else IWbemClassObject_Release( in ); + return hr; +} + +static HRESULT WINAPI class_object_PutMethod( + IWbemClassObject *iface, + LPCWSTR wszName, + LONG lFlags, + IWbemClassObject *pInSignature, + IWbemClassObject *pOutSignature ) +{ + FIXME("%p, %s, %08x, %p, %p\n", iface, debugstr_w(wszName), lFlags, pInSignature, pOutSignature); + return E_NOTIMPL; +} + +static HRESULT WINAPI class_object_DeleteMethod( + IWbemClassObject *iface, + LPCWSTR wszName ) +{ + FIXME("%p, %s\n", iface, debugstr_w(wszName)); + return E_NOTIMPL; +} + +static HRESULT WINAPI class_object_BeginMethodEnumeration( + IWbemClassObject *iface, + LONG lEnumFlags) +{ + struct class_object *co = impl_from_IWbemClassObject( iface ); + + TRACE("%p, %08x\n", iface, lEnumFlags); + + if (lEnumFlags) FIXME("flags 0x%08x not supported\n", lEnumFlags); + + if (co->iter) + { + WARN("not allowed on instance\n"); + return WBEM_E_ILLEGAL_OPERATION; + } + co->index_method = 0; + return S_OK; +} + +static HRESULT WINAPI class_object_NextMethod( + IWbemClassObject *iface, + LONG lFlags, + BSTR *pstrName, + IWbemClassObject **ppInSignature, + IWbemClassObject **ppOutSignature) +{ + struct class_object *co = impl_from_IWbemClassObject( iface ); + BSTR method; + HRESULT hr; + + TRACE("%p, %08x, %p, %p, %p\n", iface, lFlags, pstrName, ppInSignature, ppOutSignature); + + if (!(method = get_method_name( co->name, co->index_method ))) return WBEM_S_NO_MORE_DATA; + + hr = create_signature( co->name, method, PARAM_IN, ppInSignature ); + if (hr != S_OK) + { + SysFreeString( method ); + return hr; + } + hr = create_signature( co->name, method, PARAM_OUT, ppOutSignature ); + if (hr != S_OK) + { + SysFreeString( method ); + IWbemClassObject_Release( *ppInSignature ); + } + else + { + *pstrName = method; + co->index_method++; + } + return hr; +} + +static HRESULT WINAPI class_object_EndMethodEnumeration( + IWbemClassObject *iface ) +{ + struct class_object *co = impl_from_IWbemClassObject( iface ); + + TRACE("%p\n", iface); + + co->index_method = 0; + return S_OK; +} + +static HRESULT WINAPI class_object_GetMethodQualifierSet( + IWbemClassObject *iface, + LPCWSTR wszMethod, + IWbemQualifierSet **ppQualSet) +{ + FIXME("%p, %s, %p\n", iface, debugstr_w(wszMethod), ppQualSet); + return E_NOTIMPL; +} + +static HRESULT WINAPI class_object_GetMethodOrigin( + IWbemClassObject *iface, + LPCWSTR wszMethodName, + BSTR *pstrClassName) +{ + FIXME("%p, %s, %p\n", iface, debugstr_w(wszMethodName), pstrClassName); + return E_NOTIMPL; +} + +static const IWbemClassObjectVtbl class_object_vtbl = +{ + class_object_QueryInterface, + class_object_AddRef, + class_object_Release, + class_object_GetQualifierSet, + class_object_Get, + class_object_Put, + class_object_Delete, + class_object_GetNames, + class_object_BeginEnumeration, + class_object_Next, + class_object_EndEnumeration, + class_object_GetPropertyQualifierSet, + class_object_Clone, + class_object_GetObjectText, + class_object_SpawnDerivedClass, + class_object_SpawnInstance, + class_object_CompareTo, + class_object_GetPropertyOrigin, + class_object_InheritsFrom, + class_object_GetMethod, + class_object_PutMethod, + class_object_DeleteMethod, + class_object_BeginMethodEnumeration, + class_object_NextMethod, + class_object_EndMethodEnumeration, + class_object_GetMethodQualifierSet, + class_object_GetMethodOrigin +}; + +HRESULT create_class_object( const WCHAR *name, IEnumWbemClassObject *iter, UINT index, + struct record *record, IWbemClassObject **obj ) +{ + struct class_object *co; + + TRACE("%s, %p\n", debugstr_w(name), obj); + + co = heap_alloc( sizeof(*co) ); + if (!co) return E_OUTOFMEMORY; + + co->IWbemClassObject_iface.lpVtbl = &class_object_vtbl; + co->refs = 1; + if (!name) co->name = NULL; + else if (!(co->name = heap_strdupW( name ))) + { + heap_free( co ); + return E_OUTOFMEMORY; + } + co->iter = iter; + co->index = index; + co->index_method = 0; + co->index_property = 0; + co->record = record; + if (iter) IEnumWbemClassObject_AddRef( iter ); + + *obj = &co->IWbemClassObject_iface; + + TRACE("returning iface %p\n", *obj); + return S_OK; +} diff --git a/reactos/dll/win32/wbemprox/guid.c b/reactos/dll/win32/wbemprox/guid.c new file mode 100644 index 00000000000..1a8235b59c1 --- /dev/null +++ b/reactos/dll/win32/wbemprox/guid.c @@ -0,0 +1,16 @@ +/* DO NOT USE THE PRECOMPILED HEADER FOR THIS FILE! */ + +#include + +#define WIN32_NO_STATUS +#define _INC_WINDOWS +#define COM_NO_WINDOWS_H + +#include +#include +#include +#include +#include +#include + +/* NO CODE HERE, THIS IS JUST REQUIRED FOR THE GUID DEFINITIONS */ diff --git a/reactos/dll/win32/wbemprox/main.c b/reactos/dll/win32/wbemprox/main.c new file mode 100644 index 00000000000..214dfd7a41a --- /dev/null +++ b/reactos/dll/win32/wbemprox/main.c @@ -0,0 +1,155 @@ +/* + * + * Copyright 2009 Austin English + * + * 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 "wbemprox_private.h" + +#include +#include + +static HINSTANCE instance; + +typedef HRESULT (*fnCreateInstance)( LPVOID *ppObj ); + +typedef struct +{ + IClassFactory IClassFactory_iface; + fnCreateInstance pfnCreateInstance; +} wbemprox_cf; + +static inline wbemprox_cf *impl_from_IClassFactory( IClassFactory *iface ) +{ + return CONTAINING_RECORD(iface, wbemprox_cf, IClassFactory_iface); +} + +static HRESULT WINAPI wbemprox_cf_QueryInterface( IClassFactory *iface, REFIID riid, LPVOID *ppobj ) +{ + if (IsEqualGUID(riid, &IID_IUnknown) || + IsEqualGUID(riid, &IID_IClassFactory)) + { + IClassFactory_AddRef( iface ); + *ppobj = iface; + return S_OK; + } + FIXME("interface %s not implemented\n", debugstr_guid(riid)); + return E_NOINTERFACE; +} + +static ULONG WINAPI wbemprox_cf_AddRef( IClassFactory *iface ) +{ + return 2; +} + +static ULONG WINAPI wbemprox_cf_Release( IClassFactory *iface ) +{ + return 1; +} + +static HRESULT WINAPI wbemprox_cf_CreateInstance( IClassFactory *iface, LPUNKNOWN pOuter, + REFIID riid, LPVOID *ppobj ) +{ + wbemprox_cf *This = impl_from_IClassFactory( iface ); + HRESULT r; + IUnknown *punk; + + TRACE("%p %s %p\n", pOuter, debugstr_guid(riid), ppobj); + + *ppobj = NULL; + + if (pOuter) + return CLASS_E_NOAGGREGATION; + + r = This->pfnCreateInstance( (LPVOID *)&punk ); + if (FAILED(r)) + return r; + + r = IUnknown_QueryInterface( punk, riid, ppobj ); + IUnknown_Release( punk ); + return r; +} + +static HRESULT WINAPI wbemprox_cf_LockServer( IClassFactory *iface, BOOL dolock ) +{ + FIXME("(%p)->(%d)\n", iface, dolock); + return S_OK; +} + +static const struct IClassFactoryVtbl wbemprox_cf_vtbl = +{ + wbemprox_cf_QueryInterface, + wbemprox_cf_AddRef, + wbemprox_cf_Release, + wbemprox_cf_CreateInstance, + wbemprox_cf_LockServer +}; + +static wbemprox_cf wbem_locator_cf = { { &wbemprox_cf_vtbl }, WbemLocator_create }; + +BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) +{ + + switch (fdwReason) + { + case DLL_PROCESS_ATTACH: + instance = hinstDLL; + DisableThreadLibraryCalls(hinstDLL); + init_table_list(); + break; + } + + return TRUE; +} + +HRESULT WINAPI DllGetClassObject( REFCLSID rclsid, REFIID iid, LPVOID *ppv ) +{ + IClassFactory *cf = NULL; + + TRACE("%s %s %p\n", debugstr_guid(rclsid), debugstr_guid(iid), ppv); + + if (IsEqualGUID( rclsid, &CLSID_WbemLocator ) || + IsEqualGUID( rclsid, &CLSID_WbemAdministrativeLocator )) + { + cf = &wbem_locator_cf.IClassFactory_iface; + } + if (!cf) return CLASS_E_CLASSNOTAVAILABLE; + return IClassFactory_QueryInterface( cf, iid, ppv ); +} + +/*********************************************************************** + * DllCanUnloadNow (WBEMPROX.@) + */ +HRESULT WINAPI DllCanUnloadNow( void ) +{ + return S_FALSE; +} + +/*********************************************************************** + * DllRegisterServer (WBEMPROX.@) + */ +HRESULT WINAPI DllRegisterServer(void) +{ + return __wine_register_resources( instance ); +} + +/*********************************************************************** + * DllUnregisterServer (WBEMPROX.@) + */ +HRESULT WINAPI DllUnregisterServer(void) +{ + return __wine_unregister_resources( instance ); +} diff --git a/reactos/dll/win32/wbemprox/process.c b/reactos/dll/win32/wbemprox/process.c new file mode 100644 index 00000000000..0f22a8d87ee --- /dev/null +++ b/reactos/dll/win32/wbemprox/process.c @@ -0,0 +1,101 @@ +/* + * Win32_Process methods implementation + * + * Copyright 2013 Hans Leidekker for CodeWeavers + * + * 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 "wbemprox_private.h" + +static HRESULT get_owner( VARIANT *user, VARIANT *domain, VARIANT *retval ) +{ + DWORD len; + UINT error = 8; + + len = 0; + GetUserNameW( NULL, &len ); + if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) goto done; + if (!(V_BSTR( user ) = SysAllocStringLen( NULL, len - 1 ))) goto done; + if (!GetUserNameW( V_BSTR( user ), &len )) goto done; + V_VT( user ) = VT_BSTR; + + len = 0; + GetComputerNameW( NULL, &len ); + if (GetLastError() != ERROR_BUFFER_OVERFLOW) goto done; + if (!(V_BSTR( domain ) = SysAllocStringLen( NULL, len - 1 ))) goto done; + if (!GetComputerNameW( V_BSTR( domain ), &len )) goto done; + V_VT( domain ) = VT_BSTR; + + error = 0; + +done: + if (error) + { + VariantClear( user ); + VariantClear( domain ); + } + set_variant( VT_UI4, error, NULL, retval ); + return S_OK; +} + +HRESULT process_get_owner( IWbemClassObject *obj, IWbemClassObject *in, IWbemClassObject **out ) +{ + VARIANT user, domain, retval; + IWbemClassObject *sig, *out_params = NULL; + HRESULT hr; + + TRACE("%p, %p, %p\n", obj, in, out); + + hr = create_signature( class_processW, method_getownerW, PARAM_OUT, &sig ); + if (hr != S_OK) return hr; + + if (out) + { + hr = IWbemClassObject_SpawnInstance( sig, 0, &out_params ); + if (hr != S_OK) + { + IWbemClassObject_Release( sig ); + return hr; + } + } + VariantInit( &user ); + VariantInit( &domain ); + hr = get_owner( &user, &domain, &retval ); + if (hr != S_OK) goto done; + if (out_params) + { + if (!V_UI4( &retval )) + { + hr = IWbemClassObject_Put( out_params, param_userW, 0, &user, CIM_STRING ); + if (hr != S_OK) goto done; + hr = IWbemClassObject_Put( out_params, param_domainW, 0, &domain, CIM_STRING ); + if (hr != S_OK) goto done; + } + hr = IWbemClassObject_Put( out_params, param_returnvalueW, 0, &retval, CIM_UINT32 ); + } + +done: + VariantClear( &user ); + VariantClear( &domain ); + IWbemClassObject_Release( sig ); + if (hr == S_OK && out) + { + *out = out_params; + IWbemClassObject_AddRef( out_params ); + } + if (out_params) IWbemClassObject_Release( out_params ); + return hr; +} diff --git a/reactos/dll/win32/wbemprox/qualifier.c b/reactos/dll/win32/wbemprox/qualifier.c new file mode 100644 index 00000000000..c14338698c6 --- /dev/null +++ b/reactos/dll/win32/wbemprox/qualifier.c @@ -0,0 +1,264 @@ +/* + * Copyright 2013 Hans Leidekker for CodeWeavers + * + * 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 "wbemprox_private.h" + +struct qualifier_set +{ + IWbemQualifierSet IWbemQualifierSet_iface; + LONG refs; + WCHAR *class; + WCHAR *member; +}; + +static inline struct qualifier_set *impl_from_IWbemQualifierSet( + IWbemQualifierSet *iface ) +{ + return CONTAINING_RECORD(iface, struct qualifier_set, IWbemQualifierSet_iface); +} + +static ULONG WINAPI qualifier_set_AddRef( + IWbemQualifierSet *iface ) +{ + struct qualifier_set *set = impl_from_IWbemQualifierSet( iface ); + return InterlockedIncrement( &set->refs ); +} + +static ULONG WINAPI qualifier_set_Release( + IWbemQualifierSet *iface ) +{ + struct qualifier_set *set = impl_from_IWbemQualifierSet( iface ); + LONG refs = InterlockedDecrement( &set->refs ); + if (!refs) + { + TRACE("destroying %p\n", set); + heap_free( set->class ); + heap_free( set->member ); + heap_free( set ); + } + return refs; +} + +static HRESULT WINAPI qualifier_set_QueryInterface( + IWbemQualifierSet *iface, + REFIID riid, + void **ppvObject ) +{ + struct qualifier_set *set = impl_from_IWbemQualifierSet( iface ); + + TRACE("%p, %s, %p\n", set, debugstr_guid( riid ), ppvObject ); + + if ( IsEqualGUID( riid, &IID_IWbemQualifierSet ) || + IsEqualGUID( riid, &IID_IUnknown ) ) + { + *ppvObject = set; + } + else + { + FIXME("interface %s not implemented\n", debugstr_guid(riid)); + return E_NOINTERFACE; + } + IWbemQualifierSet_AddRef( iface ); + return S_OK; +} + +static HRESULT create_qualifier_enum( const WCHAR *class, const WCHAR *member, const WCHAR *name, + IEnumWbemClassObject **iter ) +{ + static const WCHAR fmtW[] = + {'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ','_','_','Q','U','A','L', + 'I','F','I','E','R','S',' ','W','H','E','R','E',' ','C','l','a','s','s','=', + '\'','%','s','\'',' ','A','N','D',' ','M','e','m','b','e','r','=','\'','%','s','\'',' ', + 'A','N','D',' ','N','a','m','e','=','\'','%','s','\'',0}; + static const WCHAR fmt2W[] = + {'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ','_','_','Q','U','A','L', + 'I','F','I','E','R','S',' ','W','H','E','R','E',' ','C','l','a','s','s','=', + '\'','%','s','\'',' ','A','N','D',' ','M','e','m','b','e','r','=','\'','%','s','\'',0}; + static const WCHAR noneW[] = {'_','_','N','O','N','E',0}; + WCHAR *query; + HRESULT hr; + int len; + + if (!member) member = noneW; + len = strlenW( class ) + strlenW( member ); + if (name) len += strlenW( name ) + SIZEOF(fmtW); + else len += SIZEOF(fmt2W); + + if (!(query = heap_alloc( len * sizeof(WCHAR) ))) return E_OUTOFMEMORY; + if (name) sprintfW( query, fmtW, class, member, name ); + else sprintfW( query, fmt2W, class, member ); + + hr = exec_query( query, iter ); + heap_free( query ); + return hr; +} + +static HRESULT get_qualifier_value( const WCHAR *class, const WCHAR *member, const WCHAR *name, + VARIANT *val, LONG *flavor ) +{ + static const WCHAR qualifiersW[] = {'_','_','Q','U','A','L','I','F','I','E','R','S',0}; + static const WCHAR intvalueW[] = {'I','n','t','e','g','e','r','V','a','l','u','e',0}; + static const WCHAR strvalueW[] = {'S','t','r','i','n','g','V','a','l','u','e',0}; + static const WCHAR flavorW[] = {'F','l','a','v','o','r',0}; + static const WCHAR typeW[] = {'T','y','p','e',0}; + IEnumWbemClassObject *iter; + IWbemClassObject *obj; + VARIANT var; + HRESULT hr; + + hr = create_qualifier_enum( class, member, name, &iter ); + if (FAILED( hr )) return hr; + + hr = create_class_object( qualifiersW, iter, 0, NULL, &obj ); + IEnumWbemClassObject_Release( iter ); + if (FAILED( hr )) return hr; + + if (flavor) + { + hr = IWbemClassObject_Get( obj, flavorW, 0, &var, NULL, NULL ); + if (hr != S_OK) goto done; + *flavor = V_I4( &var ); + } + hr = IWbemClassObject_Get( obj, typeW, 0, &var, NULL, NULL ); + if (hr != S_OK) goto done; + switch (V_UI4( &var )) + { + case CIM_STRING: + hr = IWbemClassObject_Get( obj, strvalueW, 0, val, NULL, NULL ); + break; + case CIM_SINT32: + hr = IWbemClassObject_Get( obj, intvalueW, 0, val, NULL, NULL ); + break; + default: + ERR("unhandled type %u\n", V_UI4( &var )); + break; + } + +done: + IWbemClassObject_Release( obj ); + return hr; +} + +static HRESULT WINAPI qualifier_set_Get( + IWbemQualifierSet *iface, + LPCWSTR wszName, + LONG lFlags, + VARIANT *pVal, + LONG *plFlavor ) +{ + struct qualifier_set *set = impl_from_IWbemQualifierSet( iface ); + + FIXME("%p, %s, %08x, %p, %p\n", iface, debugstr_w(wszName), lFlags, pVal, plFlavor); + return get_qualifier_value( set->class, set->member, wszName, pVal, plFlavor ); +} + +static HRESULT WINAPI qualifier_set_Put( + IWbemQualifierSet *iface, + LPCWSTR wszName, + VARIANT *pVal, + LONG lFlavor ) +{ + FIXME("%p, %s, %p, %d\n", iface, debugstr_w(wszName), pVal, lFlavor); + return E_NOTIMPL; +} + +static HRESULT WINAPI qualifier_set_Delete( + IWbemQualifierSet *iface, + LPCWSTR wszName ) +{ + FIXME("%p, %s\n", iface, debugstr_w(wszName)); + return E_NOTIMPL; +} + +static HRESULT WINAPI qualifier_set_GetNames( + IWbemQualifierSet *iface, + LONG lFlags, + SAFEARRAY **pNames ) +{ + FIXME("%p, %08x, %p\n", iface, lFlags, pNames); + return E_NOTIMPL; +} + +static HRESULT WINAPI qualifier_set_BeginEnumeration( + IWbemQualifierSet *iface, + LONG lFlags ) +{ + FIXME("%p, %08x\n", iface, lFlags); + return E_NOTIMPL; +} + +static HRESULT WINAPI qualifier_set_Next( + IWbemQualifierSet *iface, + LONG lFlags, + BSTR *pstrName, + VARIANT *pVal, + LONG *plFlavor ) +{ + FIXME("%p, %08x, %p, %p, %p\n", iface, lFlags, pstrName, pVal, plFlavor); + return E_NOTIMPL; +} + +static HRESULT WINAPI qualifier_set_EndEnumeration( + IWbemQualifierSet *iface ) +{ + FIXME("%p\n", iface); + return E_NOTIMPL; +} + +static const IWbemQualifierSetVtbl qualifier_set_vtbl = +{ + qualifier_set_QueryInterface, + qualifier_set_AddRef, + qualifier_set_Release, + qualifier_set_Get, + qualifier_set_Put, + qualifier_set_Delete, + qualifier_set_GetNames, + qualifier_set_BeginEnumeration, + qualifier_set_Next, + qualifier_set_EndEnumeration +}; + +HRESULT WbemQualifierSet_create( const WCHAR *class, const WCHAR *member, LPVOID *ppObj ) +{ + struct qualifier_set *set; + + TRACE("%p\n", ppObj); + + if (!(set = heap_alloc( sizeof(*set) ))) return E_OUTOFMEMORY; + + set->IWbemQualifierSet_iface.lpVtbl = &qualifier_set_vtbl; + if (!(set->class = heap_strdupW( class ))) + { + heap_free( set ); + return E_OUTOFMEMORY; + } + if (!member) set->member = NULL; + else if (!(set->member = heap_strdupW( member ))) + { + heap_free( set->class ); + heap_free( set ); + return E_OUTOFMEMORY; + } + set->refs = 1; + + *ppObj = &set->IWbemQualifierSet_iface; + + TRACE("returning iface %p\n", *ppObj); + return S_OK; +} diff --git a/reactos/dll/win32/wbemprox/query.c b/reactos/dll/win32/wbemprox/query.c new file mode 100644 index 00000000000..3e37f4277f8 --- /dev/null +++ b/reactos/dll/win32/wbemprox/query.c @@ -0,0 +1,1064 @@ +/* + * Copyright 2012 Hans Leidekker for CodeWeavers + * + * 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 "wbemprox_private.h" + +#include + +HRESULT create_view( const struct property *proplist, const WCHAR *class, + const struct expr *cond, struct view **ret ) +{ + struct view *view = heap_alloc( sizeof(struct view) ); + + if (!view) return E_OUTOFMEMORY; + view->proplist = proplist; + view->table = grab_table( class ); + view->cond = cond; + view->result = NULL; + view->count = 0; + *ret = view; + return S_OK; +} + +void destroy_view( struct view *view ) +{ + if (!view) return; + if (view->table) release_table( view->table ); + heap_free( view->result ); + heap_free( view ); +} + +static BOOL eval_like( const WCHAR *lstr, const WCHAR *rstr ) +{ + const WCHAR *p = lstr, *q = rstr; + + while (*p && *q) + { + if (*q == '%') + { + while (*q == '%') q++; + if (!*q) return TRUE; + while (*p && *q && toupperW( *p ) == toupperW( *q )) { p++; q++; }; + if (!*p && !*q) return TRUE; + } + if (*q != '%' && toupperW( *p++ ) != toupperW( *q++ )) return FALSE; + } + return TRUE; +} + +static HRESULT eval_strcmp( UINT op, const WCHAR *lstr, const WCHAR *rstr, LONGLONG *val ) +{ + if (!lstr || !rstr) + { + *val = 0; + return S_OK; + } + switch (op) + { + case OP_EQ: + *val = !strcmpW( lstr, rstr ); + break; + case OP_GT: + *val = strcmpW( lstr, rstr ) > 0; + break; + case OP_LT: + *val = strcmpW( lstr, rstr ) < 0; + break; + case OP_LE: + *val = strcmpW( lstr, rstr ) <= 0; + break; + case OP_GE: + *val = strcmpW( lstr, rstr ) >= 0; + break; + case OP_NE: + *val = strcmpW( lstr, rstr ); + break; + case OP_LIKE: + *val = eval_like( lstr, rstr ); + break; + default: + ERR("unhandled operator %u\n", op); + return WBEM_E_INVALID_QUERY; + } + return S_OK; +} + +static BOOL is_int( CIMTYPE type ) +{ + switch (type) + { + case CIM_SINT8: + case CIM_SINT16: + case CIM_SINT32: + case CIM_SINT64: + case CIM_UINT8: + case CIM_UINT16: + case CIM_UINT32: + case CIM_UINT64: + return TRUE; + default: + return FALSE; + } +} + +static inline BOOL is_strcmp( const struct complex_expr *expr, UINT ltype, UINT rtype ) +{ + if ((ltype == CIM_STRING || is_int( ltype )) && expr->left->type == EXPR_PROPVAL && + expr->right->type == EXPR_SVAL) return TRUE; + else if ((rtype == CIM_STRING || is_int( rtype )) && expr->right->type == EXPR_PROPVAL && + expr->left->type == EXPR_SVAL) return TRUE; + return FALSE; +} + +static inline BOOL is_boolcmp( const struct complex_expr *expr, UINT ltype, UINT rtype ) +{ + if (ltype == CIM_BOOLEAN && expr->left->type == EXPR_PROPVAL && + (expr->right->type == EXPR_SVAL || expr->right->type == EXPR_BVAL)) return TRUE; + else if (rtype == CIM_BOOLEAN && expr->right->type == EXPR_PROPVAL && + (expr->left->type == EXPR_SVAL || expr->left->type == EXPR_BVAL)) return TRUE; + return FALSE; +} + +static HRESULT eval_boolcmp( UINT op, LONGLONG lval, LONGLONG rval, UINT ltype, UINT rtype, LONGLONG *val ) +{ + static const WCHAR trueW[] = {'T','r','u','e',0}; + + if (ltype == CIM_STRING) lval = !strcmpiW( (const WCHAR *)(INT_PTR)lval, trueW ) ? -1 : 0; + else if (rtype == CIM_STRING) rval = !strcmpiW( (const WCHAR *)(INT_PTR)rval, trueW ) ? -1 : 0; + + switch (op) + { + case OP_EQ: + *val = (lval == rval); + break; + case OP_NE: + *val = (lval != rval); + break; + default: + ERR("unhandled operator %u\n", op); + return WBEM_E_INVALID_QUERY; + } + return S_OK; +} + +static UINT resolve_type( UINT left, UINT right ) +{ + switch (left) + { + case CIM_SINT8: + case CIM_SINT16: + case CIM_SINT32: + case CIM_SINT64: + case CIM_UINT8: + case CIM_UINT16: + case CIM_UINT32: + case CIM_UINT64: + switch (right) + { + case CIM_SINT8: + case CIM_SINT16: + case CIM_SINT32: + case CIM_SINT64: + case CIM_UINT8: + case CIM_UINT16: + case CIM_UINT32: + case CIM_UINT64: + return CIM_UINT64; + default: break; + } + break; + + case CIM_STRING: + if (right == CIM_STRING) return CIM_STRING; + break; + + case CIM_BOOLEAN: + if (right == CIM_BOOLEAN) return CIM_BOOLEAN; + break; + + default: + break; + } + return CIM_ILLEGAL; +} + +static const WCHAR *format_int( WCHAR *buf, CIMTYPE type, LONGLONG val ) +{ + static const WCHAR fmt_signedW[] = {'%','d',0}; + static const WCHAR fmt_unsignedW[] = {'%','u',0}; + static const WCHAR fmt_signed64W[] = {'%','I','6','4','d',0}; + static const WCHAR fmt_unsigned64W[] = {'%','I','6','4','u',0}; + + switch (type) + { + case CIM_SINT8: + case CIM_SINT16: + case CIM_SINT32: + sprintfW( buf, fmt_signedW, val ); + return buf; + + case CIM_UINT8: + case CIM_UINT16: + case CIM_UINT32: + sprintfW( buf, fmt_unsignedW, val ); + return buf; + + case CIM_SINT64: + wsprintfW( buf, fmt_signed64W, val ); + return buf; + + case CIM_UINT64: + wsprintfW( buf, fmt_unsigned64W, val ); + return buf; + + default: + ERR( "unhandled type %u\n", type ); + return NULL; + } +} + +static HRESULT eval_binary( const struct table *table, UINT row, const struct complex_expr *expr, + LONGLONG *val, UINT *type ) +{ + HRESULT lret, rret; + LONGLONG lval, rval; + UINT ltype, rtype; + + lret = eval_cond( table, row, expr->left, &lval, <ype ); + rret = eval_cond( table, row, expr->right, &rval, &rtype ); + if (lret != S_OK || rret != S_OK) return WBEM_E_INVALID_QUERY; + + *type = resolve_type( ltype, rtype ); + + if (is_boolcmp( expr, ltype, rtype )) + return eval_boolcmp( expr->op, lval, rval, ltype, rtype, val ); + + if (is_strcmp( expr, ltype, rtype )) + { + const WCHAR *lstr, *rstr; + WCHAR lbuf[21], rbuf[21]; + + if (is_int( ltype )) lstr = format_int( lbuf, ltype, lval ); + else lstr = (const WCHAR *)(INT_PTR)lval; + + if (is_int( rtype )) rstr = format_int( rbuf, rtype, rval ); + else rstr = (const WCHAR *)(INT_PTR)rval; + + return eval_strcmp( expr->op, lstr, rstr, val ); + } + switch (expr->op) + { + case OP_EQ: + *val = (lval == rval); + break; + case OP_AND: + *val = (lval && rval); + break; + case OP_OR: + *val = (lval || rval); + break; + case OP_GT: + *val = (lval > rval); + break; + case OP_LT: + *val = (lval < rval); + break; + case OP_LE: + *val = (lval <= rval); + break; + case OP_GE: + *val = (lval >= rval); + break; + case OP_NE: + *val = (lval != rval); + break; + default: + ERR("unhandled operator %u\n", expr->op); + return WBEM_E_INVALID_QUERY; + } + return S_OK; +} + +static HRESULT eval_unary( const struct table *table, UINT row, const struct complex_expr *expr, + LONGLONG *val, UINT *type ) + +{ + HRESULT hr; + UINT column; + LONGLONG lval; + + if (expr->op == OP_NOT) + { + hr = eval_cond( table, row, expr->left, &lval, type ); + if (hr != S_OK) + return hr; + *val = !lval; + return S_OK; + } + + hr = get_column_index( table, expr->left->u.propval->name, &column ); + if (hr != S_OK) + return hr; + + hr = get_value( table, row, column, &lval ); + if (hr != S_OK) + return hr; + + switch (expr->op) + { + case OP_ISNULL: + *val = !lval; + break; + case OP_NOTNULL: + *val = lval; + break; + default: + ERR("unknown operator %u\n", expr->op); + return WBEM_E_INVALID_QUERY; + } + + *type = table->columns[column].type & CIM_TYPE_MASK; + return S_OK; +} + +static HRESULT eval_propval( const struct table *table, UINT row, const struct property *propval, + LONGLONG *val, UINT *type ) + +{ + HRESULT hr; + UINT column; + + hr = get_column_index( table, propval->name, &column ); + if (hr != S_OK) + return hr; + + *type = table->columns[column].type & CIM_TYPE_MASK; + return get_value( table, row, column, val ); +} + +HRESULT eval_cond( const struct table *table, UINT row, const struct expr *cond, LONGLONG *val, UINT *type ) +{ + if (!cond) + { + *val = 1; + *type = CIM_UINT64; + return S_OK; + } + switch (cond->type) + { + case EXPR_COMPLEX: + return eval_binary( table, row, &cond->u.expr, val, type ); + + case EXPR_UNARY: + return eval_unary( table, row, &cond->u.expr, val, type ); + + case EXPR_PROPVAL: + return eval_propval( table, row, cond->u.propval, val, type ); + + case EXPR_SVAL: + *val = (INT_PTR)cond->u.sval; + *type = CIM_STRING; + return S_OK; + + case EXPR_IVAL: + *val = cond->u.ival; + *type = CIM_UINT64; + return S_OK; + + case EXPR_BVAL: + *val = cond->u.ival; + *type = CIM_BOOLEAN; + return S_OK; + + default: + ERR("invalid expression type\n"); + break; + } + return WBEM_E_INVALID_QUERY; +} + +HRESULT execute_view( struct view *view ) +{ + UINT i, j = 0, len; + + if (!view->table) return S_OK; + if (view->table->fill) + { + clear_table( view->table ); + view->table->fill( view->table, view->cond ); + } + if (!view->table->num_rows) return S_OK; + + len = min( view->table->num_rows, 16 ); + if (!(view->result = heap_alloc( len * sizeof(UINT) ))) return E_OUTOFMEMORY; + + for (i = 0; i < view->table->num_rows; i++) + { + HRESULT hr; + LONGLONG val = 0; + UINT type; + + if (j >= len) + { + UINT *tmp; + len *= 2; + if (!(tmp = heap_realloc( view->result, len * sizeof(UINT) ))) return E_OUTOFMEMORY; + view->result = tmp; + } + if ((hr = eval_cond( view->table, i, view->cond, &val, &type )) != S_OK) return hr; + if (val) view->result[j++] = i; + } + view->count = j; + return S_OK; +} + +struct query *create_query(void) +{ + struct query *query; + + if (!(query = heap_alloc( sizeof(*query) ))) return NULL; + list_init( &query->mem ); + query->refs = 1; + return query; +} + +void free_query( struct query *query ) +{ + struct list *mem, *next; + + if (!query) return; + destroy_view( query->view ); + LIST_FOR_EACH_SAFE( mem, next, &query->mem ) { heap_free( mem ); } + heap_free( query ); +} + +struct query *addref_query( struct query *query ) +{ + InterlockedIncrement( &query->refs ); + return query; +} + +void release_query( struct query *query ) +{ + if (!InterlockedDecrement( &query->refs )) free_query( query ); +} + +HRESULT exec_query( const WCHAR *str, IEnumWbemClassObject **result ) +{ + HRESULT hr; + struct query *query; + + *result = NULL; + if (!(query = create_query())) return E_OUTOFMEMORY; + hr = parse_query( str, &query->view, &query->mem ); + if (hr != S_OK) goto done; + hr = execute_view( query->view ); + if (hr != S_OK) goto done; + hr = EnumWbemClassObject_create( query, (void **)result ); + +done: + release_query( query ); + return hr; +} + +BOOL is_selected_prop( const struct view *view, const WCHAR *name ) +{ + const struct property *prop = view->proplist; + + if (!prop) return TRUE; + while (prop) + { + if (!strcmpiW( prop->name, name )) return TRUE; + prop = prop->next; + } + return FALSE; +} + +static BOOL is_system_prop( const WCHAR *name ) +{ + return (name[0] == '_' && name[1] == '_'); +} + +static BSTR build_servername( const struct view *view ) +{ + WCHAR server[MAX_COMPUTERNAME_LENGTH + 1], *p; + DWORD len = sizeof(server)/sizeof(server[0]); + + if (view->proplist) return NULL; + + if (!(GetComputerNameW( server, &len ))) return NULL; + for (p = server; *p; p++) *p = toupperW( *p ); + return SysAllocString( server ); +} + +static BSTR build_classname( const struct view *view ) +{ + return SysAllocString( view->table->name ); +} + +static BSTR build_namespace( const struct view *view ) +{ + static const WCHAR cimv2W[] = {'R','O','O','T','\\','C','I','M','V','2',0}; + + if (view->proplist) return NULL; + return SysAllocString( cimv2W ); +} + +static BSTR build_proplist( const struct view *view, UINT index, UINT count, UINT *len ) +{ + static const WCHAR fmtW[] = {'%','s','=','%','s',0}; + UINT i, j, offset, row = view->result[index]; + BSTR *values, ret = NULL; + + if (!(values = heap_alloc( count * sizeof(BSTR) ))) return NULL; + + *len = j = 0; + for (i = 0; i < view->table->num_cols; i++) + { + if (view->table->columns[i].type & COL_FLAG_KEY) + { + const WCHAR *name = view->table->columns[i].name; + + values[j] = get_value_bstr( view->table, row, i ); + *len += strlenW( fmtW ) + strlenW( name ) + strlenW( values[j] ); + j++; + } + } + if ((ret = SysAllocStringLen( NULL, *len ))) + { + offset = j = 0; + for (i = 0; i < view->table->num_cols; i++) + { + if (view->table->columns[i].type & COL_FLAG_KEY) + { + const WCHAR *name = view->table->columns[i].name; + + offset += sprintfW( ret + offset, fmtW, name, values[j] ); + if (j < count - 1) ret[offset++] = ','; + j++; + } + } + } + for (i = 0; i < count; i++) SysFreeString( values[i] ); + heap_free( values ); + return ret; +} + +static UINT count_key_columns( const struct view *view ) +{ + UINT i, num_keys = 0; + + for (i = 0; i < view->table->num_cols; i++) + { + if (view->table->columns[i].type & COL_FLAG_KEY) num_keys++; + } + return num_keys; +} + +static BSTR build_relpath( const struct view *view, UINT index, const WCHAR *name ) +{ + static const WCHAR fmtW[] = {'%','s','.','%','s',0}; + BSTR class, proplist, ret = NULL; + UINT num_keys, len; + + if (view->proplist) return NULL; + + if (!(class = build_classname( view ))) return NULL; + if (!(num_keys = count_key_columns( view ))) return class; + if (!(proplist = build_proplist( view, index, num_keys, &len ))) goto done; + + len += strlenW( fmtW ) + SysStringLen( class ); + if (!(ret = SysAllocStringLen( NULL, len ))) goto done; + sprintfW( ret, fmtW, class, proplist ); + +done: + SysFreeString( class ); + SysFreeString( proplist ); + return ret; +} + +static BSTR build_path( const struct view *view, UINT index, const WCHAR *name ) +{ + static const WCHAR fmtW[] = {'\\','\\','%','s','\\','%','s',':','%','s',0}; + BSTR server, namespace = NULL, relpath = NULL, ret = NULL; + UINT len; + + if (view->proplist) return NULL; + + if (!(server = build_servername( view ))) return NULL; + if (!(namespace = build_namespace( view ))) goto done; + if (!(relpath = build_relpath( view, index, name ))) goto done; + + len = strlenW( fmtW ) + SysStringLen( server ) + SysStringLen( namespace ) + SysStringLen( relpath ); + if (!(ret = SysAllocStringLen( NULL, len ))) goto done; + sprintfW( ret, fmtW, server, namespace, relpath ); + +done: + SysFreeString( server ); + SysFreeString( namespace ); + SysFreeString( relpath ); + return ret; +} + +BOOL is_method( const struct table *table, UINT column ) +{ + return table->columns[column].type & COL_FLAG_METHOD; +} + +static UINT count_properties( const struct view *view ) +{ + UINT i, num_props = 0; + + for (i = 0; i < view->table->num_cols; i++) + { + if (!is_method( view->table, i)) num_props++; + } + return num_props; +} + +static UINT count_selected_properties( const struct view *view ) +{ + const struct property *prop = view->proplist; + UINT count; + + if (!prop) return count_properties( view ); + + count = 1; + while ((prop = prop->next)) count++; + return count; +} + +static HRESULT get_system_propval( const struct view *view, UINT index, const WCHAR *name, + VARIANT *ret, CIMTYPE *type, LONG *flavor ) +{ + static const WCHAR classW[] = {'_','_','C','L','A','S','S',0}; + static const WCHAR genusW[] = {'_','_','G','E','N','U','S',0}; + static const WCHAR pathW[] = {'_','_','P','A','T','H',0}; + static const WCHAR namespaceW[] = {'_','_','N','A','M','E','S','P','A','C','E',0}; + static const WCHAR propcountW[] = {'_','_','P','R','O','P','E','R','T','Y','_','C','O','U','N','T',0}; + static const WCHAR relpathW[] = {'_','_','R','E','L','P','A','T','H',0}; + static const WCHAR serverW[] = {'_','_','S','E','R','V','E','R',0}; + + if (flavor) *flavor = WBEM_FLAVOR_ORIGIN_SYSTEM; + + if (!strcmpiW( name, classW )) + { + V_VT( ret ) = VT_BSTR; + V_BSTR( ret ) = build_classname( view ); + if (type) *type = CIM_STRING; + return S_OK; + } + if (!strcmpiW( name, genusW )) + { + V_VT( ret ) = VT_I4; + V_I4( ret ) = WBEM_GENUS_INSTANCE; /* FIXME */ + if (type) *type = CIM_SINT32; + return S_OK; + } + else if (!strcmpiW( name, namespaceW )) + { + V_VT( ret ) = VT_BSTR; + V_BSTR( ret ) = build_namespace( view ); + if (type) *type = CIM_STRING; + return S_OK; + } + else if (!strcmpiW( name, pathW )) + { + V_VT( ret ) = VT_BSTR; + V_BSTR( ret ) = build_path( view, index, name ); + if (type) *type = CIM_STRING; + return S_OK; + } + if (!strcmpiW( name, propcountW )) + { + V_VT( ret ) = VT_I4; + V_I4( ret ) = count_selected_properties( view ); + if (type) *type = CIM_SINT32; + return S_OK; + } + else if (!strcmpiW( name, relpathW )) + { + V_VT( ret ) = VT_BSTR; + V_BSTR( ret ) = build_relpath( view, index, name ); + if (type) *type = CIM_STRING; + return S_OK; + } + else if (!strcmpiW( name, serverW )) + { + V_VT( ret ) = VT_BSTR; + V_BSTR( ret ) = build_servername( view ); + if (type) *type = CIM_STRING; + return S_OK; + } + FIXME("system property %s not implemented\n", debugstr_w(name)); + return WBEM_E_NOT_FOUND; +} + +VARTYPE to_vartype( CIMTYPE type ) +{ + switch (type) + { + case CIM_BOOLEAN: return VT_BOOL; + case CIM_STRING: + case CIM_DATETIME: return VT_BSTR; + case CIM_SINT8: return VT_I1; + case CIM_UINT8: return VT_UI1; + case CIM_SINT16: return VT_I2; + case CIM_UINT16: return VT_UI2; + case CIM_SINT32: return VT_I4; + case CIM_UINT32: return VT_UI4; + case CIM_SINT64: return VT_I8; + case CIM_UINT64: return VT_UI8; + default: + ERR("unhandled type %u\n", type); + break; + } + return 0; +} + +SAFEARRAY *to_safearray( const struct array *array, CIMTYPE type ) +{ + SAFEARRAY *ret; + UINT size = get_type_size( type ); + VARTYPE vartype = to_vartype( type ); + LONG i; + + if (!array || !(ret = SafeArrayCreateVector( vartype, 0, array->count ))) return NULL; + + for (i = 0; i < array->count; i++) + { + void *ptr = (char *)array->ptr + i * size; + if (vartype == VT_BSTR) + { + BSTR str = SysAllocString( *(const WCHAR **)ptr ); + if (!str || SafeArrayPutElement( ret, &i, str ) != S_OK) + { + SysFreeString( str ); + SafeArrayDestroy( ret ); + return NULL; + } + SysFreeString( str ); + } + else if (SafeArrayPutElement( ret, &i, ptr ) != S_OK) + { + SafeArrayDestroy( ret ); + return NULL; + } + } + return ret; +} + +void set_variant( VARTYPE type, LONGLONG val, void *val_ptr, VARIANT *ret ) +{ + if (type & VT_ARRAY) + { + V_VT( ret ) = type; + V_ARRAY( ret ) = val_ptr; + return; + } + switch (type) + { + case VT_BOOL: + V_BOOL( ret ) = val; + break; + case VT_BSTR: + V_BSTR( ret ) = val_ptr; + break; + case VT_I1: + V_I1( ret ) = val; + break; + case VT_UI1: + V_UI1( ret ) = val; + break; + case VT_I2: + V_I2( ret ) = val; + break; + case VT_UI2: + V_UI2( ret ) = val; + break; + case VT_I4: + V_I4( ret ) = val; + break; + case VT_UI4: + V_UI4( ret ) = val; + break; + case VT_NULL: + break; + default: + ERR("unhandled variant type %u\n", type); + return; + } + V_VT( ret ) = type; +} + +HRESULT get_propval( const struct view *view, UINT index, const WCHAR *name, VARIANT *ret, + CIMTYPE *type, LONG *flavor ) +{ + HRESULT hr; + UINT column, row; + VARTYPE vartype; + void *val_ptr = NULL; + LONGLONG val; + + if (is_system_prop( name )) return get_system_propval( view, index, name, ret, type, flavor ); + if (!view->count || !is_selected_prop( view, name )) return WBEM_E_NOT_FOUND; + + hr = get_column_index( view->table, name, &column ); + if (hr != S_OK || is_method( view->table, column )) return WBEM_E_NOT_FOUND; + + row = view->result[index]; + hr = get_value( view->table, row, column, &val ); + if (hr != S_OK) return hr; + + vartype = view->table->columns[column].vartype; + if (view->table->columns[column].type & CIM_FLAG_ARRAY) + { + CIMTYPE basetype = view->table->columns[column].type & CIM_TYPE_MASK; + + val_ptr = to_safearray( (const struct array *)(INT_PTR)val, basetype ); + if (!val_ptr) vartype = VT_NULL; + else if (!vartype) vartype = to_vartype( basetype ) | VT_ARRAY; + goto done; + } + switch (view->table->columns[column].type & COL_TYPE_MASK) + { + case CIM_BOOLEAN: + if (!vartype) vartype = VT_BOOL; + break; + case CIM_STRING: + case CIM_DATETIME: + if (val) + { + vartype = VT_BSTR; + val_ptr = SysAllocString( (const WCHAR *)(INT_PTR)val ); + } + else + vartype = VT_NULL; + break; + case CIM_SINT8: + if (!vartype) vartype = VT_I1; + break; + case CIM_UINT8: + if (!vartype) vartype = VT_UI1; + break; + case CIM_SINT16: + if (!vartype) vartype = VT_I2; + break; + case CIM_UINT16: + if (!vartype) vartype = VT_UI2; + break; + case CIM_SINT32: + if (!vartype) vartype = VT_I4; + break; + case CIM_UINT32: + if (!vartype) vartype = VT_UI4; + break; + case CIM_SINT64: + vartype = VT_BSTR; + val_ptr = get_value_bstr( view->table, row, column ); + break; + case CIM_UINT64: + vartype = VT_BSTR; + val_ptr = get_value_bstr( view->table, row, column ); + break; + default: + ERR("unhandled column type %u\n", view->table->columns[column].type); + return WBEM_E_FAILED; + } + +done: + set_variant( vartype, val, val_ptr, ret ); + if (type) *type = view->table->columns[column].type & COL_TYPE_MASK; + if (flavor) *flavor = 0; + return S_OK; +} + +static CIMTYPE to_cimtype( VARTYPE type ) +{ + switch (type) + { + case VT_BOOL: return CIM_BOOLEAN; + case VT_BSTR: return CIM_STRING; + case VT_I1: return CIM_SINT8; + case VT_UI1: return CIM_UINT8; + case VT_I2: return CIM_SINT16; + case VT_UI2: return CIM_UINT16; + case VT_I4: return CIM_SINT32; + case VT_UI4: return CIM_UINT32; + case VT_I8: return CIM_SINT64; + case VT_UI8: return CIM_UINT64; + default: + ERR("unhandled type %u\n", type); + break; + } + return 0; +} + +static struct array *to_array( VARIANT *var, CIMTYPE *type ) +{ + struct array *ret; + LONG bound, i; + VARTYPE vartype; + CIMTYPE basetype; + UINT size; + + if (SafeArrayGetVartype( V_ARRAY( var ), &vartype ) != S_OK) return NULL; + if (!(basetype = to_cimtype( vartype ))) return NULL; + if (SafeArrayGetUBound( V_ARRAY( var ), 1, &bound ) != S_OK) return NULL; + if (!(ret = heap_alloc( sizeof(struct array) ))) return NULL; + + ret->count = bound + 1; + size = get_type_size( basetype ); + if (!(ret->ptr = heap_alloc_zero( ret->count * size ))) + { + heap_free( ret ); + return NULL; + } + for (i = 0; i < ret->count; i++) + { + void *ptr = (char *)ret->ptr + i * size; + if (vartype == VT_BSTR) + { + BSTR str; + if (SafeArrayGetElement( V_ARRAY( var ), &i, &str ) != S_OK) + { + destroy_array( ret, basetype ); + return NULL; + } + *(WCHAR **)ptr = heap_strdupW( str ); + SysFreeString( str ); + if (!*(WCHAR **)ptr) + { + destroy_array( ret, basetype ); + return NULL; + } + } + else if (SafeArrayGetElement( V_ARRAY( var ), &i, ptr ) != S_OK) + { + destroy_array( ret, basetype ); + return NULL; + } + } + *type = basetype | CIM_FLAG_ARRAY; + return ret; +} + +HRESULT to_longlong( VARIANT *var, LONGLONG *val, CIMTYPE *type ) +{ + if (!var) + { + *val = 0; + return S_OK; + } + if (V_VT( var ) & VT_ARRAY) + { + *val = (INT_PTR)to_array( var, type ); + if (!*val) return E_OUTOFMEMORY; + return S_OK; + } + switch (V_VT( var )) + { + case VT_BOOL: + *val = V_BOOL( var ); + *type = CIM_BOOLEAN; + break; + case VT_BSTR: + *val = (INT_PTR)heap_strdupW( V_BSTR( var ) ); + if (!*val) return E_OUTOFMEMORY; + *type = CIM_STRING; + break; + case VT_I2: + *val = V_I2( var ); + *type = CIM_SINT16; + break; + case VT_UI2: + *val = V_UI2( var ); + *type = CIM_UINT16; + break; + case VT_I4: + *val = V_I4( var ); + *type = CIM_SINT32; + break; + case VT_UI4: + *val = V_UI4( var ); + *type = CIM_UINT32; + break; + case VT_NULL: + *val = 0; + break; + default: + ERR("unhandled type %u\n", V_VT( var )); + return WBEM_E_FAILED; + } + return S_OK; +} + +HRESULT put_propval( const struct view *view, UINT index, const WCHAR *name, VARIANT *var, CIMTYPE type ) +{ + HRESULT hr; + UINT column, row = view->result[index]; + LONGLONG val; + + hr = get_column_index( view->table, name, &column ); + if (hr != S_OK) + { + FIXME("no support for creating new properties\n"); + return WBEM_E_FAILED; + } + if (is_method( view->table, column ) || !(view->table->columns[column].type & COL_FLAG_DYNAMIC)) + return WBEM_E_FAILED; + + hr = to_longlong( var, &val, &type ); + if (hr != S_OK) return hr; + + return set_value( view->table, row, column, val, type ); +} + +HRESULT get_properties( const struct view *view, LONG flags, SAFEARRAY **props ) +{ + SAFEARRAY *sa; + BSTR str; + UINT i, num_props = count_selected_properties( view ); + LONG j; + + if (!(sa = SafeArrayCreateVector( VT_BSTR, 0, num_props ))) return E_OUTOFMEMORY; + + for (i = 0, j = 0; i < view->table->num_cols; i++) + { + BOOL is_system; + + if (is_method( view->table, i )) continue; + if (!is_selected_prop( view, view->table->columns[i].name )) continue; + + is_system = is_system_prop( view->table->columns[i].name ); + if ((flags & WBEM_FLAG_NONSYSTEM_ONLY) && is_system) continue; + else if ((flags & WBEM_FLAG_SYSTEM_ONLY) && !is_system) continue; + + str = SysAllocString( view->table->columns[i].name ); + if (!str || SafeArrayPutElement( sa, &j, str ) != S_OK) + { + SysFreeString( str ); + SafeArrayDestroy( sa ); + return E_OUTOFMEMORY; + } + SysFreeString( str ); + j++; + } + *props = sa; + return S_OK; +} diff --git a/reactos/dll/win32/wbemprox/reg.c b/reactos/dll/win32/wbemprox/reg.c new file mode 100644 index 00000000000..247dcaafa30 --- /dev/null +++ b/reactos/dll/win32/wbemprox/reg.c @@ -0,0 +1,374 @@ +/* + * StdRegProv implementation + * + * Copyright 2012 Hans Leidekker for CodeWeavers + * + * 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 "wbemprox_private.h" + +#include + +static HRESULT to_bstr_array( BSTR *strings, DWORD count, VARIANT *var ) +{ + SAFEARRAY *sa; + HRESULT hr; + LONG i; + + if (!(sa = SafeArrayCreateVector( VT_BSTR, 0, count ))) return E_OUTOFMEMORY; + for (i = 0; i < count; i++) + { + if ((hr = SafeArrayPutElement( sa, &i, strings[i] )) != S_OK) + { + SafeArrayDestroy( sa ); + return hr; + } + } + set_variant( VT_BSTR|VT_ARRAY, 0, sa, var ); + return S_OK; +} + +static void free_bstr_array( BSTR *strings, DWORD count ) +{ + while (count--) + SysFreeString( *(strings++) ); +} + +static HRESULT to_i4_array( DWORD *values, DWORD count, VARIANT *var ) +{ + SAFEARRAY *sa; + HRESULT hr; + LONG i; + + if (!(sa = SafeArrayCreateVector( VT_I4, 0, count ))) return E_OUTOFMEMORY; + for (i = 0; i < count; i++) + { + if ((hr = SafeArrayPutElement( sa, &i, &values[i] )) != S_OK) + { + SafeArrayDestroy( sa ); + return hr; + } + } + set_variant( VT_I4|VT_ARRAY, 0, sa, var ); + return S_OK; +} + +static HRESULT enum_key( HKEY root, const WCHAR *subkey, VARIANT *names, VARIANT *retval ) +{ + HKEY hkey; + HRESULT hr = S_OK; + WCHAR buf[256]; + BSTR *strings, *tmp; + DWORD count = 2, len = sizeof(buf)/sizeof(buf[0]); + LONG res, i = 0; + + TRACE("%p, %s\n", root, debugstr_w(subkey)); + + if (!(strings = heap_alloc( count * sizeof(BSTR) ))) return E_OUTOFMEMORY; + if ((res = RegOpenKeyExW( root, subkey, 0, KEY_ENUMERATE_SUB_KEYS, &hkey ))) + { + set_variant( VT_UI4, res, NULL, retval ); + heap_free( strings ); + return S_OK; + } + for (;;) + { + if (i >= count) + { + count *= 2; + if (!(tmp = heap_realloc( strings, count * sizeof(BSTR) ))) + { + RegCloseKey( hkey ); + return E_OUTOFMEMORY; + } + strings = tmp; + } + if ((res = RegEnumKeyW( hkey, i, buf, len )) == ERROR_NO_MORE_ITEMS) + { + if (i) res = ERROR_SUCCESS; + break; + } + if (res) break; + if (!(strings[i] = SysAllocString( buf ))) + { + for (i--; i >= 0; i--) SysFreeString( strings[i] ); + hr = E_OUTOFMEMORY; + break; + } + i++; + } + if (hr == S_OK && !res) + { + hr = to_bstr_array( strings, i, names ); + free_bstr_array( strings, i ); + } + set_variant( VT_UI4, res, NULL, retval ); + RegCloseKey( hkey ); + heap_free( strings ); + return hr; +} + +HRESULT reg_enum_key( IWbemClassObject *obj, IWbemClassObject *in, IWbemClassObject **out ) +{ + VARIANT defkey, subkey, names, retval; + IWbemClassObject *sig, *out_params = NULL; + HRESULT hr; + + TRACE("%p, %p\n", in, out); + + hr = IWbemClassObject_Get( in, param_defkeyW, 0, &defkey, NULL, NULL ); + if (hr != S_OK) return hr; + hr = IWbemClassObject_Get( in, param_subkeynameW, 0, &subkey, NULL, NULL ); + if (hr != S_OK) return hr; + + hr = create_signature( class_stdregprovW, method_enumkeyW, PARAM_OUT, &sig ); + if (hr != S_OK) + { + VariantClear( &subkey ); + return hr; + } + if (out) + { + hr = IWbemClassObject_SpawnInstance( sig, 0, &out_params ); + if (hr != S_OK) + { + VariantClear( &subkey ); + IWbemClassObject_Release( sig ); + return hr; + } + } + VariantInit( &names ); + hr = enum_key( (HKEY)(INT_PTR)V_I4(&defkey), V_BSTR(&subkey), &names, &retval ); + if (hr != S_OK) goto done; + if (out_params) + { + if (!V_UI4( &retval )) + { + hr = IWbemClassObject_Put( out_params, param_namesW, 0, &names, CIM_STRING|CIM_FLAG_ARRAY ); + if (hr != S_OK) goto done; + } + hr = IWbemClassObject_Put( out_params, param_returnvalueW, 0, &retval, CIM_UINT32 ); + } + +done: + VariantClear( &names ); + VariantClear( &subkey ); + IWbemClassObject_Release( sig ); + if (hr == S_OK && out) + { + *out = out_params; + IWbemClassObject_AddRef( out_params ); + } + if (out_params) IWbemClassObject_Release( out_params ); + return hr; +} + +static HRESULT enum_values( HKEY root, const WCHAR *subkey, VARIANT *names, VARIANT *types, VARIANT *retval ) +{ + HKEY hkey = NULL; + HRESULT hr = S_OK; + BSTR *value_names = NULL; + DWORD count, buflen, len, *value_types = NULL; + LONG res, i = 0; + WCHAR *buf = NULL; + + TRACE("%p, %s\n", root, debugstr_w(subkey)); + + if ((res = RegOpenKeyExW( root, subkey, 0, KEY_QUERY_VALUE, &hkey ))) goto done; + if ((res = RegQueryInfoKeyW( hkey, NULL, NULL, NULL, NULL, NULL, NULL, &count, &buflen, NULL, NULL, NULL ))) + goto done; + + hr = E_OUTOFMEMORY; + if (!(buf = heap_alloc( (buflen + 1) * sizeof(WCHAR) ))) goto done; + if (!(value_names = heap_alloc( count * sizeof(BSTR) ))) goto done; + if (!(value_types = heap_alloc( count * sizeof(DWORD) ))) goto done; + + hr = S_OK; + for (;;) + { + len = buflen + 1; + res = RegEnumValueW( hkey, i, buf, &len, NULL, &value_types[i], NULL, NULL ); + if (res == ERROR_NO_MORE_ITEMS) + { + if (i) res = ERROR_SUCCESS; + break; + } + if (res) break; + if (!(value_names[i] = SysAllocString( buf ))) + { + for (i--; i >= 0; i--) SysFreeString( value_names[i] ); + hr = E_OUTOFMEMORY; + break; + } + i++; + } + if (hr == S_OK && !res) + { + hr = to_bstr_array( value_names, i, names ); + free_bstr_array( value_names, i ); + if (hr == S_OK) hr = to_i4_array( value_types, i, types ); + } + +done: + set_variant( VT_UI4, res, NULL, retval ); + RegCloseKey( hkey ); + heap_free( value_names ); + heap_free( value_types ); + heap_free( buf ); + return hr; +} + +HRESULT reg_enum_values( IWbemClassObject *obj, IWbemClassObject *in, IWbemClassObject **out ) +{ + VARIANT defkey, subkey, names, types, retval; + IWbemClassObject *sig, *out_params = NULL; + HRESULT hr; + + TRACE("%p, %p\n", in, out); + + hr = IWbemClassObject_Get( in, param_defkeyW, 0, &defkey, NULL, NULL ); + if (hr != S_OK) return hr; + hr = IWbemClassObject_Get( in, param_subkeynameW, 0, &subkey, NULL, NULL ); + if (hr != S_OK) return hr; + + hr = create_signature( class_stdregprovW, method_enumvaluesW, PARAM_OUT, &sig ); + if (hr != S_OK) + { + VariantClear( &subkey ); + return hr; + } + if (out) + { + hr = IWbemClassObject_SpawnInstance( sig, 0, &out_params ); + if (hr != S_OK) + { + VariantClear( &subkey ); + IWbemClassObject_Release( sig ); + return hr; + } + } + VariantInit( &names ); + VariantInit( &types ); + hr = enum_values( (HKEY)(INT_PTR)V_I4(&defkey), V_BSTR(&subkey), &names, &types, &retval ); + if (hr != S_OK) goto done; + if (out_params) + { + if (!V_UI4( &retval )) + { + hr = IWbemClassObject_Put( out_params, param_namesW, 0, &names, CIM_STRING|CIM_FLAG_ARRAY ); + if (hr != S_OK) goto done; + hr = IWbemClassObject_Put( out_params, param_typesW, 0, &types, CIM_SINT32|CIM_FLAG_ARRAY ); + if (hr != S_OK) goto done; + } + hr = IWbemClassObject_Put( out_params, param_returnvalueW, 0, &retval, CIM_UINT32 ); + } + +done: + VariantClear( &types ); + VariantClear( &names ); + VariantClear( &subkey ); + IWbemClassObject_Release( sig ); + if (hr == S_OK && out) + { + *out = out_params; + IWbemClassObject_AddRef( out_params ); + } + if (out_params) IWbemClassObject_Release( out_params ); + return hr; +} + +static HRESULT get_stringvalue( HKEY root, const WCHAR *subkey, const WCHAR *name, VARIANT *value, VARIANT *retval ) +{ + HRESULT hr = S_OK; + BSTR str = NULL; + DWORD size; + LONG res; + + TRACE("%p, %s, %s\n", root, debugstr_w(subkey), debugstr_w(name)); + + if ((res = RegGetValueW( root, subkey, name, RRF_RT_REG_SZ, NULL, NULL, &size ))) goto done; + if (!(str = SysAllocStringLen( NULL, size / sizeof(WCHAR) - 1 ))) + { + hr = E_OUTOFMEMORY; + goto done; + } + if (!(res = RegGetValueW( root, subkey, name, RRF_RT_REG_SZ, NULL, str, &size ))) + set_variant( VT_BSTR, 0, str, value ); + +done: + set_variant( VT_UI4, res, NULL, retval ); + if (res) SysFreeString( str ); + return hr; +} + +HRESULT reg_get_stringvalue( IWbemClassObject *obj, IWbemClassObject *in, IWbemClassObject **out ) +{ + VARIANT defkey, subkey, name, value, retval; + IWbemClassObject *sig, *out_params = NULL; + HRESULT hr; + + TRACE("%p, %p\n", in, out); + + hr = IWbemClassObject_Get( in, param_defkeyW, 0, &defkey, NULL, NULL ); + if (hr != S_OK) return hr; + hr = IWbemClassObject_Get( in, param_subkeynameW, 0, &subkey, NULL, NULL ); + if (hr != S_OK) return hr; + hr = IWbemClassObject_Get( in, param_valuenameW, 0, &name, NULL, NULL ); + if (hr != S_OK) return hr; + + hr = create_signature( class_stdregprovW, method_getstringvalueW, PARAM_OUT, &sig ); + if (hr != S_OK) + { + VariantClear( &name ); + VariantClear( &subkey ); + return hr; + } + if (out) + { + hr = IWbemClassObject_SpawnInstance( sig, 0, &out_params ); + if (hr != S_OK) + { + VariantClear( &name ); + VariantClear( &subkey ); + IWbemClassObject_Release( sig ); + return hr; + } + } + VariantInit( &value ); + hr = get_stringvalue( (HKEY)(INT_PTR)V_I4(&defkey), V_BSTR(&subkey), V_BSTR(&name), &value, &retval ); + if (hr != S_OK) goto done; + if (out_params) + { + if (!V_UI4( &retval )) + { + hr = IWbemClassObject_Put( out_params, param_valueW, 0, &value, CIM_STRING ); + if (hr != S_OK) goto done; + } + hr = IWbemClassObject_Put( out_params, param_returnvalueW, 0, &retval, CIM_UINT32 ); + } + +done: + VariantClear( &name ); + VariantClear( &subkey ); + IWbemClassObject_Release( sig ); + if (hr == S_OK && out) + { + *out = out_params; + IWbemClassObject_AddRef( out_params ); + } + if (out_params) IWbemClassObject_Release( out_params ); + return hr; +} diff --git a/reactos/dll/win32/wbemprox/security.c b/reactos/dll/win32/wbemprox/security.c new file mode 100644 index 00000000000..8b109294d22 --- /dev/null +++ b/reactos/dll/win32/wbemprox/security.c @@ -0,0 +1,209 @@ +/* + * __SystemSecurity implementation + * + * Copyright 2014 Vincent Povirk for CodeWeavers + * + * 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 "wbemprox_private.h" + +#include + +static HRESULT to_byte_array( void *data, DWORD size, VARIANT *var ) +{ + SAFEARRAY *sa; + void *sadata; + HRESULT hr; + + if (!(sa = SafeArrayCreateVector( VT_UI1, 0, size ))) return E_OUTOFMEMORY; + + hr = SafeArrayAccessData( sa, &sadata ); + + if (SUCCEEDED(hr)) + { + memcpy( sadata, data, size ); + + SafeArrayUnaccessData( sa ); + } + else + { + SafeArrayDestroy( sa ); + return hr; + } + + set_variant( VT_UI1|VT_ARRAY, 0, sa, var ); + return S_OK; +} + +static HRESULT get_sd( SECURITY_DESCRIPTOR **sd, DWORD *size ) +{ + BYTE sid_admin_buffer[SECURITY_MAX_SID_SIZE]; + SID *sid_admin = (SID*)sid_admin_buffer; + BYTE sid_network_buffer[SECURITY_MAX_SID_SIZE]; + SID *sid_network = (SID*)sid_network_buffer; + BYTE sid_local_buffer[SECURITY_MAX_SID_SIZE]; + SID *sid_local = (SID*)sid_local_buffer; + BYTE sid_users_buffer[SECURITY_MAX_SID_SIZE]; + SID *sid_users = (SID*)sid_users_buffer; + BYTE acl_buffer[sizeof(ACL) + 4 * (sizeof(ACCESS_ALLOWED_ACE) - sizeof(DWORD) + SECURITY_MAX_SID_SIZE)]; + ACL *acl = (ACL*)acl_buffer; + DWORD sid_size; + SECURITY_DESCRIPTOR absolute_sd; + HRESULT hr = S_OK; + + sid_size = sizeof(sid_admin_buffer); + CreateWellKnownSid( WinBuiltinAdministratorsSid, NULL, sid_admin, &sid_size ); + + sid_size = sizeof(sid_network_buffer); + CreateWellKnownSid( WinNetworkServiceSid, NULL, sid_network, &sid_size ); + + sid_size = sizeof(sid_local_buffer); + CreateWellKnownSid( WinLocalServiceSid, NULL, sid_local, &sid_size ); + + sid_size = sizeof(sid_users_buffer); + CreateWellKnownSid( WinAuthenticatedUserSid, NULL, sid_users, &sid_size ); + + InitializeAcl( acl, sizeof(acl_buffer), ACL_REVISION ); + + AddAccessAllowedAceEx( acl, ACL_REVISION, CONTAINER_INHERIT_ACE|INHERITED_ACE, + ADS_RIGHT_DS_CREATE_CHILD|ADS_RIGHT_DS_DELETE_CHILD|ADS_RIGHT_ACTRL_DS_LIST|ADS_RIGHT_DS_SELF| + ADS_RIGHT_DS_READ_PROP|ADS_RIGHT_DS_WRITE_PROP|READ_CONTROL|WRITE_DAC, + sid_admin ); + + AddAccessAllowedAceEx( acl, ACL_REVISION, CONTAINER_INHERIT_ACE|INHERITED_ACE, + ADS_RIGHT_DS_CREATE_CHILD|ADS_RIGHT_DS_DELETE_CHILD|ADS_RIGHT_DS_READ_PROP, + sid_network ); + + AddAccessAllowedAceEx( acl, ACL_REVISION, CONTAINER_INHERIT_ACE|INHERITED_ACE, + ADS_RIGHT_DS_CREATE_CHILD|ADS_RIGHT_DS_DELETE_CHILD|ADS_RIGHT_DS_READ_PROP, + sid_local ); + + AddAccessAllowedAceEx( acl, ACL_REVISION, CONTAINER_INHERIT_ACE|INHERITED_ACE, + ADS_RIGHT_DS_CREATE_CHILD|ADS_RIGHT_DS_DELETE_CHILD|ADS_RIGHT_DS_READ_PROP, + sid_users ); + + InitializeSecurityDescriptor( &absolute_sd, SECURITY_DESCRIPTOR_REVISION ); + + SetSecurityDescriptorOwner( &absolute_sd, sid_admin, TRUE ); + SetSecurityDescriptorGroup( &absolute_sd, sid_admin, TRUE ); + SetSecurityDescriptorDacl( &absolute_sd, TRUE, acl, TRUE ); + + *size = GetSecurityDescriptorLength( &absolute_sd ); + + *sd = HeapAlloc( GetProcessHeap(), 0, *size ); + if (!*sd) + hr = E_OUTOFMEMORY; + + if (SUCCEEDED(hr)) + { + if (!MakeSelfRelativeSD(&absolute_sd, *sd, size)) { + HeapFree( GetProcessHeap(), 0, *sd ); + *sd = NULL; + hr = E_FAIL; + } + } + + return hr; +} + +HRESULT security_get_sd( IWbemClassObject *obj, IWbemClassObject *in, IWbemClassObject **out ) +{ + VARIANT var_sd, retval; + IWbemClassObject *sig, *out_params = NULL; + HRESULT hr, ret; + SECURITY_DESCRIPTOR *sd; + DWORD sd_size; + + TRACE("%p, %p\n", in, out); + + hr = create_signature( class_systemsecurityW, method_getsdW, PARAM_OUT, &sig ); + + if (SUCCEEDED(hr)) + { + hr = IWbemClassObject_SpawnInstance( sig, 0, &out_params ); + + IWbemClassObject_Release( sig ); + } + + if (SUCCEEDED(hr)) + { + ret = get_sd( &sd, &sd_size ); + + if (SUCCEEDED(ret)) + { + VariantInit( &var_sd ); + + hr = to_byte_array( sd, sd_size, &var_sd ); + + if (SUCCEEDED(hr)) + hr = IWbemClassObject_Put( out_params, param_sdW, 0, &var_sd, CIM_UINT8|CIM_FLAG_ARRAY ); + + HeapFree( GetProcessHeap(), 0, sd ); + VariantClear( &var_sd ); + } + + if (SUCCEEDED(hr)) + { + set_variant( VT_UI4, ret, NULL, &retval ); + hr = IWbemClassObject_Put( out_params, param_returnvalueW, 0, &retval, CIM_UINT32 ); + } + + if (SUCCEEDED(hr) && out) + { + *out = out_params; + IWbemClassObject_AddRef( out_params ); + } + + IWbemClassObject_Release( out_params ); + } + + return hr; +} + + +HRESULT security_set_sd( IWbemClassObject *obj, IWbemClassObject *in, IWbemClassObject **out ) +{ + VARIANT retval; + IWbemClassObject *sig, *out_params = NULL; + HRESULT hr; + + FIXME("stub\n"); + + hr = create_signature( class_systemsecurityW, method_setsdW, PARAM_OUT, &sig ); + + if (SUCCEEDED(hr)) + { + hr = IWbemClassObject_SpawnInstance( sig, 0, &out_params ); + + IWbemClassObject_Release( sig ); + } + + if (SUCCEEDED(hr)) + { + set_variant( VT_UI4, S_OK, NULL, &retval ); + hr = IWbemClassObject_Put( out_params, param_returnvalueW, 0, &retval, CIM_UINT32 ); + + if (SUCCEEDED(hr) && out) + { + *out = out_params; + IWbemClassObject_AddRef( out_params ); + } + + IWbemClassObject_Release( out_params ); + } + + return hr; +} diff --git a/reactos/dll/win32/wbemprox/service.c b/reactos/dll/win32/wbemprox/service.c new file mode 100644 index 00000000000..6c09f76af1a --- /dev/null +++ b/reactos/dll/win32/wbemprox/service.c @@ -0,0 +1,269 @@ +/* + * Win32_Service methods implementation + * + * Copyright 2012 Hans Leidekker for CodeWeavers + * + * 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 "wbemprox_private.h" + +static UINT map_error( DWORD error ) +{ + switch (error) + { + case ERROR_SUCCESS: return 0; + case ERROR_ACCESS_DENIED: return 2; + case ERROR_DEPENDENT_SERVICES_RUNNING: return 3; + case ERROR_INVALID_SERVICE_CONTROL: return 4; + case ERROR_SERVICE_CANNOT_ACCEPT_CTRL: return 5; + case ERROR_SERVICE_NOT_ACTIVE: return 6; + case ERROR_SERVICE_REQUEST_TIMEOUT: return 7; + case ERROR_SERVICE_ALREADY_RUNNING: return 10; + default: + WARN("unknown error %u\n", error); + break; + } + return 8; +} + +static HRESULT control_service( const WCHAR *name, DWORD control, VARIANT *retval ) +{ + SC_HANDLE manager, service = NULL; + SERVICE_STATUS status; + UINT error = 0; + + if (!(manager = OpenSCManagerW( NULL, NULL, SC_MANAGER_ENUMERATE_SERVICE ))) + { + error = map_error( GetLastError() ); + goto done; + } + if (!(service = OpenServiceW( manager, name, SERVICE_STOP|SERVICE_START|SERVICE_PAUSE_CONTINUE ))) + { + error = map_error( GetLastError() ); + goto done; + } + if (!ControlService( service, control, &status )) error = map_error( GetLastError() ); + CloseServiceHandle( service ); + +done: + set_variant( VT_UI4, error, NULL, retval ); + if (manager) CloseServiceHandle( manager ); + return S_OK; +} + +HRESULT service_pause_service( IWbemClassObject *obj, IWbemClassObject *in, IWbemClassObject **out ) +{ + VARIANT name, retval; + IWbemClassObject *sig, *out_params = NULL; + HRESULT hr; + + TRACE("%p, %p, %p\n", obj, in, out); + + hr = IWbemClassObject_Get( obj, prop_nameW, 0, &name, NULL, NULL ); + if (hr != S_OK) return hr; + + hr = create_signature( class_serviceW, method_pauseserviceW, PARAM_OUT, &sig ); + if (hr != S_OK) + { + VariantClear( &name ); + return hr; + } + if (out) + { + hr = IWbemClassObject_SpawnInstance( sig, 0, &out_params ); + if (hr != S_OK) + { + VariantClear( &name ); + IWbemClassObject_Release( sig ); + return hr; + } + } + hr = control_service( V_BSTR(&name), SERVICE_CONTROL_PAUSE, &retval ); + if (hr != S_OK) goto done; + + if (out_params) + hr = IWbemClassObject_Put( out_params, param_returnvalueW, 0, &retval, CIM_UINT32 ); + +done: + VariantClear( &name ); + IWbemClassObject_Release( sig ); + if (hr == S_OK && out) + { + *out = out_params; + IWbemClassObject_AddRef( out_params ); + } + if (out_params) IWbemClassObject_Release( out_params ); + return hr; +} + +HRESULT service_resume_service( IWbemClassObject *obj, IWbemClassObject *in, IWbemClassObject **out ) +{ + VARIANT name, retval; + IWbemClassObject *sig, *out_params = NULL; + HRESULT hr; + + TRACE("%p, %p, %p\n", obj, in, out); + + hr = IWbemClassObject_Get( obj, prop_nameW, 0, &name, NULL, NULL ); + if (hr != S_OK) return hr; + + hr = create_signature( class_serviceW, method_resumeserviceW, PARAM_OUT, &sig ); + if (hr != S_OK) + { + VariantClear( &name ); + return hr; + } + if (out) + { + hr = IWbemClassObject_SpawnInstance( sig, 0, &out_params ); + if (hr != S_OK) + { + VariantClear( &name ); + IWbemClassObject_Release( sig ); + return hr; + } + } + hr = control_service( V_BSTR(&name), SERVICE_CONTROL_CONTINUE, &retval ); + if (hr != S_OK) goto done; + + if (out_params) + hr = IWbemClassObject_Put( out_params, param_returnvalueW, 0, &retval, CIM_UINT32 ); + +done: + VariantClear( &name ); + IWbemClassObject_Release( sig ); + if (hr == S_OK && out) + { + *out = out_params; + IWbemClassObject_AddRef( out_params ); + } + if (out_params) IWbemClassObject_Release( out_params ); + return hr; +} + +static HRESULT start_service( const WCHAR *name, VARIANT *retval ) +{ + SC_HANDLE manager, service = NULL; + UINT error = 0; + + if (!(manager = OpenSCManagerW( NULL, NULL, SC_MANAGER_ENUMERATE_SERVICE ))) + { + error = map_error( GetLastError() ); + goto done; + } + if (!(service = OpenServiceW( manager, name, SERVICE_START ))) + { + error = map_error( GetLastError() ); + goto done; + } + if (!StartServiceW( service, 0, NULL )) error = map_error( GetLastError() ); + CloseServiceHandle( service ); + +done: + set_variant( VT_UI4, error, NULL, retval ); + if (manager) CloseServiceHandle( manager ); + return S_OK; +} + +HRESULT service_start_service( IWbemClassObject *obj, IWbemClassObject *in, IWbemClassObject **out ) +{ + VARIANT name, retval; + IWbemClassObject *sig, *out_params = NULL; + HRESULT hr; + + TRACE("%p, %p, %p\n", obj, in, out); + + hr = IWbemClassObject_Get( obj, prop_nameW, 0, &name, NULL, NULL ); + if (hr != S_OK) return hr; + + hr = create_signature( class_serviceW, method_startserviceW, PARAM_OUT, &sig ); + if (hr != S_OK) + { + VariantClear( &name ); + return hr; + } + if (out) + { + hr = IWbemClassObject_SpawnInstance( sig, 0, &out_params ); + if (hr != S_OK) + { + VariantClear( &name ); + IWbemClassObject_Release( sig ); + return hr; + } + } + hr = start_service( V_BSTR(&name), &retval ); + if (hr != S_OK) goto done; + + if (out_params) + hr = IWbemClassObject_Put( out_params, param_returnvalueW, 0, &retval, CIM_UINT32 ); + +done: + VariantClear( &name ); + IWbemClassObject_Release( sig ); + if (hr == S_OK && out) + { + *out = out_params; + IWbemClassObject_AddRef( out_params ); + } + if (out_params) IWbemClassObject_Release( out_params ); + return hr; +} + +HRESULT service_stop_service( IWbemClassObject *obj, IWbemClassObject *in, IWbemClassObject **out ) +{ + VARIANT name, retval; + IWbemClassObject *sig, *out_params = NULL; + HRESULT hr; + + TRACE("%p, %p, %p\n", obj, in, out); + + hr = IWbemClassObject_Get( obj, prop_nameW, 0, &name, NULL, NULL ); + if (hr != S_OK) return hr; + + hr = create_signature( class_serviceW, method_stopserviceW, PARAM_OUT, &sig ); + if (hr != S_OK) + { + VariantClear( &name ); + return hr; + } + if (out) + { + hr = IWbemClassObject_SpawnInstance( sig, 0, &out_params ); + if (hr != S_OK) + { + VariantClear( &name ); + IWbemClassObject_Release( sig ); + return hr; + } + } + hr = control_service( V_BSTR(&name), SERVICE_CONTROL_STOP, &retval ); + if (hr != S_OK) goto done; + + if (out_params) + hr = IWbemClassObject_Put( out_params, param_returnvalueW, 0, &retval, CIM_UINT32 ); + +done: + VariantClear( &name ); + IWbemClassObject_Release( sig ); + if (hr == S_OK && out) + { + *out = out_params; + IWbemClassObject_AddRef( out_params ); + } + if (out_params) IWbemClassObject_Release( out_params ); + return hr; +} diff --git a/reactos/dll/win32/wbemprox/services.c b/reactos/dll/win32/wbemprox/services.c new file mode 100644 index 00000000000..70d1442d8cf --- /dev/null +++ b/reactos/dll/win32/wbemprox/services.c @@ -0,0 +1,888 @@ +/* + * Copyright 2012 Hans Leidekker for CodeWeavers + * + * 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 "wbemprox_private.h" + +struct client_security +{ + IClientSecurity IClientSecurity_iface; +}; + +static inline struct client_security *impl_from_IClientSecurity( IClientSecurity *iface ) +{ + return CONTAINING_RECORD( iface, struct client_security, IClientSecurity_iface ); +} + +static HRESULT WINAPI client_security_QueryInterface( + IClientSecurity *iface, + REFIID riid, + void **ppvObject ) +{ + struct client_security *cs = impl_from_IClientSecurity( iface ); + + TRACE("%p %s %p\n", cs, debugstr_guid( riid ), ppvObject ); + + if ( IsEqualGUID( riid, &IID_IClientSecurity ) || + IsEqualGUID( riid, &IID_IUnknown ) ) + { + *ppvObject = cs; + } + else + { + FIXME("interface %s not implemented\n", debugstr_guid(riid)); + return E_NOINTERFACE; + } + IClientSecurity_AddRef( iface ); + return S_OK; +} + +static ULONG WINAPI client_security_AddRef( + IClientSecurity *iface ) +{ + FIXME("%p\n", iface); + return 2; +} + +static ULONG WINAPI client_security_Release( + IClientSecurity *iface ) +{ + FIXME("%p\n", iface); + return 1; +} + +static HRESULT WINAPI client_security_QueryBlanket( + IClientSecurity *iface, + IUnknown *pProxy, + DWORD *pAuthnSvc, + DWORD *pAuthzSvc, + OLECHAR **pServerPrincName, + DWORD *pAuthnLevel, + DWORD *pImpLevel, + void **pAuthInfo, + DWORD *pCapabilities ) +{ + FIXME("\n"); + return WBEM_E_FAILED; +} + +static HRESULT WINAPI client_security_SetBlanket( + IClientSecurity *iface, + IUnknown *pProxy, + DWORD AuthnSvc, + DWORD AuthzSvc, + OLECHAR *pServerPrincName, + DWORD AuthnLevel, + DWORD ImpLevel, + void *pAuthInfo, + DWORD Capabilities ) +{ + static const OLECHAR defaultW[] = + {'<','C','O','L','E','_','D','E','F','A','U','L','T','_','P','R','I','N','C','I','P','A','L','>',0}; + const OLECHAR *princname = (pServerPrincName == COLE_DEFAULT_PRINCIPAL) ? defaultW : pServerPrincName; + + FIXME("%p, %p, %u, %u, %s, %u, %u, %p, 0x%08x\n", iface, pProxy, AuthnSvc, AuthzSvc, + debugstr_w(princname), AuthnLevel, ImpLevel, pAuthInfo, Capabilities); + return WBEM_NO_ERROR; +} + +static HRESULT WINAPI client_security_CopyProxy( + IClientSecurity *iface, + IUnknown *pProxy, + IUnknown **ppCopy ) +{ + FIXME("\n"); + return WBEM_E_FAILED; +} + +static const IClientSecurityVtbl client_security_vtbl = +{ + client_security_QueryInterface, + client_security_AddRef, + client_security_Release, + client_security_QueryBlanket, + client_security_SetBlanket, + client_security_CopyProxy +}; + +IClientSecurity client_security = { &client_security_vtbl }; + +struct async_header +{ + IWbemObjectSink *sink; + void (*proc)( struct async_header * ); + HANDLE cancel; + HANDLE wait; +}; + +struct async_query +{ + struct async_header hdr; + WCHAR *str; +}; + +static void free_async( struct async_header *async ) +{ + if (async->sink) IWbemObjectSink_Release( async->sink ); + CloseHandle( async->cancel ); + CloseHandle( async->wait ); + heap_free( async ); +} + +static BOOL init_async( struct async_header *async, IWbemObjectSink *sink, + void (*proc)(struct async_header *) ) +{ + if (!(async->wait = CreateEventW( NULL, FALSE, FALSE, NULL ))) return FALSE; + if (!(async->cancel = CreateEventW( NULL, FALSE, FALSE, NULL ))) + { + CloseHandle( async->wait ); + return FALSE; + } + async->proc = proc; + async->sink = sink; + IWbemObjectSink_AddRef( sink ); + return TRUE; +} + +static DWORD CALLBACK async_proc( LPVOID param ) +{ + struct async_header *async = param; + HANDLE wait = async->wait; + + async->proc( async ); + + WaitForSingleObject( async->cancel, INFINITE ); + SetEvent( wait ); + return ERROR_SUCCESS; +} + +static HRESULT queue_async( struct async_header *async ) +{ + if (QueueUserWorkItem( async_proc, async, WT_EXECUTELONGFUNCTION )) return S_OK; + return HRESULT_FROM_WIN32( GetLastError() ); +} + +struct wbem_services +{ + IWbemServices IWbemServices_iface; + LONG refs; + CRITICAL_SECTION cs; + WCHAR *namespace; + struct async_header *async; +}; + +static inline struct wbem_services *impl_from_IWbemServices( IWbemServices *iface ) +{ + return CONTAINING_RECORD( iface, struct wbem_services, IWbemServices_iface ); +} + +static ULONG WINAPI wbem_services_AddRef( + IWbemServices *iface ) +{ + struct wbem_services *ws = impl_from_IWbemServices( iface ); + return InterlockedIncrement( &ws->refs ); +} + +static ULONG WINAPI wbem_services_Release( + IWbemServices *iface ) +{ + struct wbem_services *ws = impl_from_IWbemServices( iface ); + LONG refs = InterlockedDecrement( &ws->refs ); + if (!refs) + { + TRACE("destroying %p\n", ws); + + EnterCriticalSection( &ws->cs ); + if (ws->async) SetEvent( ws->async->cancel ); + LeaveCriticalSection( &ws->cs ); + if (ws->async) + { + WaitForSingleObject( ws->async->wait, INFINITE ); + free_async( ws->async ); + } + ws->cs.DebugInfo->Spare[0] = 0; + DeleteCriticalSection( &ws->cs ); + heap_free( ws->namespace ); + heap_free( ws ); + } + return refs; +} + +static HRESULT WINAPI wbem_services_QueryInterface( + IWbemServices *iface, + REFIID riid, + void **ppvObject ) +{ + struct wbem_services *ws = impl_from_IWbemServices( iface ); + + TRACE("%p %s %p\n", ws, debugstr_guid( riid ), ppvObject ); + + if ( IsEqualGUID( riid, &IID_IWbemServices ) || + IsEqualGUID( riid, &IID_IUnknown ) ) + { + *ppvObject = ws; + } + else if ( IsEqualGUID( riid, &IID_IClientSecurity ) ) + { + *ppvObject = &client_security; + return S_OK; + } + else + { + FIXME("interface %s not implemented\n", debugstr_guid(riid)); + return E_NOINTERFACE; + } + IWbemServices_AddRef( iface ); + return S_OK; +} + +static HRESULT WINAPI wbem_services_OpenNamespace( + IWbemServices *iface, + const BSTR strNamespace, + LONG lFlags, + IWbemContext *pCtx, + IWbemServices **ppWorkingNamespace, + IWbemCallResult **ppResult ) +{ + static const WCHAR cimv2W[] = {'c','i','m','v','2',0}; + static const WCHAR defaultW[] = {'d','e','f','a','u','l','t',0}; + struct wbem_services *ws = impl_from_IWbemServices( iface ); + + TRACE("%p, %s, 0x%08x, %p, %p, %p\n", iface, debugstr_w(strNamespace), lFlags, + pCtx, ppWorkingNamespace, ppResult); + + if ((strcmpiW( strNamespace, cimv2W ) && strcmpiW( strNamespace, defaultW )) || ws->namespace) + return WBEM_E_INVALID_NAMESPACE; + + return WbemServices_create( cimv2W, (void **)ppWorkingNamespace ); +} + +static HRESULT WINAPI wbem_services_CancelAsyncCall( + IWbemServices *iface, + IWbemObjectSink *pSink ) +{ + struct wbem_services *services = impl_from_IWbemServices( iface ); + struct async_header *async; + + TRACE("%p, %p\n", iface, pSink); + + if (!pSink) return WBEM_E_INVALID_PARAMETER; + + EnterCriticalSection( &services->cs ); + + if (!(async = services->async)) + { + LeaveCriticalSection( &services->cs ); + return WBEM_E_INVALID_PARAMETER; + } + services->async = NULL; + SetEvent( async->cancel ); + + LeaveCriticalSection( &services->cs ); + + WaitForSingleObject( async->wait, INFINITE ); + free_async( async ); + return S_OK; +} + +static HRESULT WINAPI wbem_services_QueryObjectSink( + IWbemServices *iface, + LONG lFlags, + IWbemObjectSink **ppResponseHandler ) +{ + FIXME("\n"); + return WBEM_E_FAILED; +} + +struct path +{ + WCHAR *class; + UINT class_len; + WCHAR *filter; + UINT filter_len; +}; + +static HRESULT parse_path( const WCHAR *str, struct path **ret ) +{ + struct path *path; + const WCHAR *p = str, *q; + UINT len; + + if (!(path = heap_alloc_zero( sizeof(*path) ))) return E_OUTOFMEMORY; + + while (*p && *p != '.') p++; + + len = p - str; + if (!(path->class = heap_alloc( (len + 1) * sizeof(WCHAR) ))) + { + heap_free( path ); + return E_OUTOFMEMORY; + } + memcpy( path->class, str, len * sizeof(WCHAR) ); + path->class[len] = 0; + path->class_len = len; + + if (p[0] == '.' && p[1]) + { + q = ++p; + while (*q) q++; + + len = q - p; + if (!(path->filter = heap_alloc( (len + 1) * sizeof(WCHAR) ))) + { + heap_free( path->class ); + heap_free( path ); + return E_OUTOFMEMORY; + } + memcpy( path->filter, p, len * sizeof(WCHAR) ); + path->filter[len] = 0; + path->filter_len = len; + } + *ret = path; + return S_OK; +} + +static void free_path( struct path *path ) +{ + heap_free( path->class ); + heap_free( path->filter ); + heap_free( path ); +} + +static WCHAR *query_from_path( const struct path *path ) +{ + static const WCHAR selectW[] = + {'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ','%','s',' ', + 'W','H','E','R','E',' ','%','s',0}; + static const WCHAR select_allW[] = + {'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ',0}; + WCHAR *query; + UINT len; + + if (path->filter) + { + len = path->class_len + path->filter_len + SIZEOF(selectW); + if (!(query = heap_alloc( len * sizeof(WCHAR) ))) return NULL; + sprintfW( query, selectW, path->class, path->filter ); + } + else + { + len = path->class_len + SIZEOF(select_allW); + if (!(query = heap_alloc( len * sizeof(WCHAR) ))) return NULL; + strcpyW( query, select_allW ); + strcatW( query, path->class ); + } + return query; +} + +static HRESULT create_instance_enum( const struct path *path, IEnumWbemClassObject **iter ) +{ + WCHAR *query; + HRESULT hr; + + if (!(query = query_from_path( path ))) return E_OUTOFMEMORY; + hr = exec_query( query, iter ); + heap_free( query ); + return hr; +} + +HRESULT get_object( const WCHAR *object_path, IWbemClassObject **obj ) +{ + IEnumWbemClassObject *iter; + struct path *path; + HRESULT hr; + + hr = parse_path( object_path, &path ); + if (hr != S_OK) return hr; + + hr = create_instance_enum( path, &iter ); + if (hr != S_OK) + { + free_path( path ); + return hr; + } + hr = create_class_object( path->class, iter, 0, NULL, obj ); + IEnumWbemClassObject_Release( iter ); + free_path( path ); + return hr; +} + +static HRESULT WINAPI wbem_services_GetObject( + IWbemServices *iface, + const BSTR strObjectPath, + LONG lFlags, + IWbemContext *pCtx, + IWbemClassObject **ppObject, + IWbemCallResult **ppCallResult ) +{ + TRACE("%p, %s, 0x%08x, %p, %p, %p\n", iface, debugstr_w(strObjectPath), lFlags, + pCtx, ppObject, ppCallResult); + + if (lFlags) FIXME("unsupported flags 0x%08x\n", lFlags); + + if (!strObjectPath || !strObjectPath[0]) + return create_class_object( NULL, NULL, 0, NULL, ppObject ); + + return get_object( strObjectPath, ppObject ); +} + +static HRESULT WINAPI wbem_services_GetObjectAsync( + IWbemServices *iface, + const BSTR strObjectPath, + LONG lFlags, + IWbemContext *pCtx, + IWbemObjectSink *pResponseHandler ) +{ + FIXME("\n"); + return WBEM_E_FAILED; +} + +static HRESULT WINAPI wbem_services_PutClass( + IWbemServices *iface, + IWbemClassObject *pObject, + LONG lFlags, + IWbemContext *pCtx, + IWbemCallResult **ppCallResult ) +{ + FIXME("\n"); + return WBEM_E_FAILED; +} + +static HRESULT WINAPI wbem_services_PutClassAsync( + IWbemServices *iface, + IWbemClassObject *pObject, + LONG lFlags, + IWbemContext *pCtx, + IWbemObjectSink *pResponseHandler ) +{ + FIXME("\n"); + return WBEM_E_FAILED; +} + +static HRESULT WINAPI wbem_services_DeleteClass( + IWbemServices *iface, + const BSTR strClass, + LONG lFlags, + IWbemContext *pCtx, + IWbemCallResult **ppCallResult ) +{ + FIXME("\n"); + return WBEM_E_FAILED; +} + +static HRESULT WINAPI wbem_services_DeleteClassAsync( + IWbemServices *iface, + const BSTR strClass, + LONG lFlags, + IWbemContext *pCtx, + IWbemObjectSink *pResponseHandler ) +{ + FIXME("\n"); + return WBEM_E_FAILED; +} + +static HRESULT WINAPI wbem_services_CreateClassEnum( + IWbemServices *iface, + const BSTR strSuperclass, + LONG lFlags, + IWbemContext *pCtx, + IEnumWbemClassObject **ppEnum ) +{ + FIXME("\n"); + return WBEM_E_FAILED; +} + +static HRESULT WINAPI wbem_services_CreateClassEnumAsync( + IWbemServices *iface, + const BSTR strSuperclass, + LONG lFlags, + IWbemContext *pCtx, + IWbemObjectSink *pResponseHandler ) +{ + FIXME("\n"); + return WBEM_E_FAILED; +} + +static HRESULT WINAPI wbem_services_PutInstance( + IWbemServices *iface, + IWbemClassObject *pInst, + LONG lFlags, + IWbemContext *pCtx, + IWbemCallResult **ppCallResult ) +{ + FIXME("\n"); + return WBEM_E_FAILED; +} + +static HRESULT WINAPI wbem_services_PutInstanceAsync( + IWbemServices *iface, + IWbemClassObject *pInst, + LONG lFlags, + IWbemContext *pCtx, + IWbemObjectSink *pResponseHandler ) +{ + FIXME("\n"); + return WBEM_E_FAILED; +} + +static HRESULT WINAPI wbem_services_DeleteInstance( + IWbemServices *iface, + const BSTR strObjectPath, + LONG lFlags, + IWbemContext *pCtx, + IWbemCallResult **ppCallResult ) +{ + FIXME("\n"); + return WBEM_E_FAILED; +} + +static HRESULT WINAPI wbem_services_DeleteInstanceAsync( + IWbemServices *iface, + const BSTR strObjectPath, + LONG lFlags, + IWbemContext *pCtx, + IWbemObjectSink *pResponseHandler ) +{ + FIXME("\n"); + return WBEM_E_FAILED; +} + +static HRESULT WINAPI wbem_services_CreateInstanceEnum( + IWbemServices *iface, + const BSTR strClass, + LONG lFlags, + IWbemContext *pCtx, + IEnumWbemClassObject **ppEnum ) +{ + struct path *path; + HRESULT hr; + + TRACE("%p, %s, 0%08x, %p, %p\n", iface, debugstr_w(strClass), lFlags, pCtx, ppEnum); + + if (lFlags) FIXME("unsupported flags 0x%08x\n", lFlags); + + hr = parse_path( strClass, &path ); + if (hr != S_OK) return hr; + + hr = create_instance_enum( path, ppEnum ); + free_path( path ); + return hr; +} + +static HRESULT WINAPI wbem_services_CreateInstanceEnumAsync( + IWbemServices *iface, + const BSTR strFilter, + LONG lFlags, + IWbemContext *pCtx, + IWbemObjectSink *pResponseHandler ) +{ + FIXME("\n"); + return WBEM_E_FAILED; +} + +static HRESULT WINAPI wbem_services_ExecQuery( + IWbemServices *iface, + const BSTR strQueryLanguage, + const BSTR strQuery, + LONG lFlags, + IWbemContext *pCtx, + IEnumWbemClassObject **ppEnum ) +{ + static const WCHAR wqlW[] = {'W','Q','L',0}; + + TRACE("%p, %s, %s, 0x%08x, %p, %p\n", iface, debugstr_w(strQueryLanguage), + debugstr_w(strQuery), lFlags, pCtx, ppEnum); + + if (!strQueryLanguage || !strQuery || !strQuery[0]) return WBEM_E_INVALID_PARAMETER; + if (strcmpiW( strQueryLanguage, wqlW )) return WBEM_E_INVALID_QUERY_TYPE; + return exec_query( strQuery, ppEnum ); +} + +static void async_exec_query( struct async_header *hdr ) +{ + struct async_query *query = (struct async_query *)hdr; + IEnumWbemClassObject *result; + IWbemClassObject *obj; + ULONG count; + HRESULT hr; + + hr = exec_query( query->str, &result ); + if (hr == S_OK) + { + for (;;) + { + IEnumWbemClassObject_Next( result, WBEM_INFINITE, 1, &obj, &count ); + if (!count) break; + IWbemObjectSink_Indicate( query->hdr.sink, 1, &obj ); + IWbemClassObject_Release( obj ); + } + IEnumWbemClassObject_Release( result ); + } + IWbemObjectSink_SetStatus( query->hdr.sink, WBEM_STATUS_COMPLETE, hr, NULL, NULL ); + heap_free( query->str ); +} + +static HRESULT WINAPI wbem_services_ExecQueryAsync( + IWbemServices *iface, + const BSTR strQueryLanguage, + const BSTR strQuery, + LONG lFlags, + IWbemContext *pCtx, + IWbemObjectSink *pResponseHandler ) +{ + struct wbem_services *services = impl_from_IWbemServices( iface ); + IWbemObjectSink *sink; + HRESULT hr = E_OUTOFMEMORY; + struct async_header *async; + struct async_query *query; + + TRACE("%p, %s, %s, 0x%08x, %p, %p\n", iface, debugstr_w(strQueryLanguage), debugstr_w(strQuery), + lFlags, pCtx, pResponseHandler); + + if (!pResponseHandler) return WBEM_E_INVALID_PARAMETER; + + hr = IWbemObjectSink_QueryInterface( pResponseHandler, &IID_IWbemObjectSink, (void **)&sink ); + if (FAILED(hr)) return hr; + + EnterCriticalSection( &services->cs ); + + if (services->async) + { + FIXME("handle more than one pending async\n"); + hr = WBEM_E_FAILED; + goto done; + } + if (!(query = heap_alloc_zero( sizeof(*query) ))) goto done; + async = (struct async_header *)query; + + if (!(init_async( async, sink, async_exec_query ))) + { + free_async( async ); + goto done; + } + if (!(query->str = heap_strdupW( strQuery ))) + { + free_async( async ); + goto done; + } + hr = queue_async( async ); + if (hr == S_OK) services->async = async; + else + { + heap_free( query->str ); + free_async( async ); + } + +done: + LeaveCriticalSection( &services->cs ); + IWbemObjectSink_Release( sink ); + return hr; +} + +static HRESULT WINAPI wbem_services_ExecNotificationQuery( + IWbemServices *iface, + const BSTR strQueryLanguage, + const BSTR strQuery, + LONG lFlags, + IWbemContext *pCtx, + IEnumWbemClassObject **ppEnum ) +{ + FIXME("\n"); + return WBEM_E_FAILED; +} + +static HRESULT WINAPI wbem_services_ExecNotificationQueryAsync( + IWbemServices *iface, + const BSTR strQueryLanguage, + const BSTR strQuery, + LONG lFlags, + IWbemContext *pCtx, + IWbemObjectSink *pResponseHandler ) +{ + struct wbem_services *services = impl_from_IWbemServices( iface ); + IWbemObjectSink *sink; + HRESULT hr = E_OUTOFMEMORY; + struct async_header *async; + struct async_query *query; + + TRACE("%p, %s, %s, 0x%08x, %p, %p\n", iface, debugstr_w(strQueryLanguage), debugstr_w(strQuery), + lFlags, pCtx, pResponseHandler); + + if (!pResponseHandler) return WBEM_E_INVALID_PARAMETER; + + hr = IWbemObjectSink_QueryInterface( pResponseHandler, &IID_IWbemObjectSink, (void **)&sink ); + if (FAILED(hr)) return hr; + + EnterCriticalSection( &services->cs ); + + if (services->async) + { + FIXME("handle more than one pending async\n"); + hr = WBEM_E_FAILED; + goto done; + } + if (!(query = heap_alloc_zero( sizeof(*query) ))) goto done; + async = (struct async_header *)query; + + if (!(init_async( async, sink, async_exec_query ))) + { + free_async( async ); + goto done; + } + if (!(query->str = heap_strdupW( strQuery ))) + { + free_async( async ); + goto done; + } + hr = queue_async( async ); + if (hr == S_OK) services->async = async; + else + { + heap_free( query->str ); + free_async( async ); + } + +done: + LeaveCriticalSection( &services->cs ); + IWbemObjectSink_Release( sink ); + return hr; +} + +static HRESULT WINAPI wbem_services_ExecMethod( + IWbemServices *iface, + const BSTR strObjectPath, + const BSTR strMethodName, + LONG lFlags, + IWbemContext *pCtx, + IWbemClassObject *pInParams, + IWbemClassObject **ppOutParams, + IWbemCallResult **ppCallResult ) +{ + IEnumWbemClassObject *result = NULL; + IWbemClassObject *obj = NULL; + struct query *query = NULL; + struct path *path; + WCHAR *str; + class_method *func; + HRESULT hr; + + TRACE("%p, %s, %s, %08x, %p, %p, %p, %p\n", iface, debugstr_w(strObjectPath), + debugstr_w(strMethodName), lFlags, pCtx, pInParams, ppOutParams, ppCallResult); + + if (lFlags) FIXME("flags %08x not supported\n", lFlags); + + if ((hr = parse_path( strObjectPath, &path )) != S_OK) return hr; + if (!(str = query_from_path( path ))) + { + hr = E_OUTOFMEMORY; + goto done; + } + if (!(query = create_query())) + { + hr = E_OUTOFMEMORY; + goto done; + } + hr = parse_query( str, &query->view, &query->mem ); + if (hr != S_OK) goto done; + + hr = execute_view( query->view ); + if (hr != S_OK) goto done; + + hr = EnumWbemClassObject_create( query, (void **)&result ); + if (hr != S_OK) goto done; + + hr = create_class_object( query->view->table->name, result, 0, NULL, &obj ); + if (hr != S_OK) goto done; + + hr = get_method( query->view->table, strMethodName, &func ); + if (hr != S_OK) goto done; + + hr = func( obj, pInParams, ppOutParams ); + +done: + if (result) IEnumWbemClassObject_Release( result ); + if (obj) IWbemClassObject_Release( obj ); + free_query( query ); + free_path( path ); + heap_free( str ); + return hr; +} + +static HRESULT WINAPI wbem_services_ExecMethodAsync( + IWbemServices *iface, + const BSTR strObjectPath, + const BSTR strMethodName, + LONG lFlags, + IWbemContext *pCtx, + IWbemClassObject *pInParams, + IWbemObjectSink *pResponseHandler ) +{ + FIXME("\n"); + return WBEM_E_FAILED; +} + +static const IWbemServicesVtbl wbem_services_vtbl = +{ + wbem_services_QueryInterface, + wbem_services_AddRef, + wbem_services_Release, + wbem_services_OpenNamespace, + wbem_services_CancelAsyncCall, + wbem_services_QueryObjectSink, + wbem_services_GetObject, + wbem_services_GetObjectAsync, + wbem_services_PutClass, + wbem_services_PutClassAsync, + wbem_services_DeleteClass, + wbem_services_DeleteClassAsync, + wbem_services_CreateClassEnum, + wbem_services_CreateClassEnumAsync, + wbem_services_PutInstance, + wbem_services_PutInstanceAsync, + wbem_services_DeleteInstance, + wbem_services_DeleteInstanceAsync, + wbem_services_CreateInstanceEnum, + wbem_services_CreateInstanceEnumAsync, + wbem_services_ExecQuery, + wbem_services_ExecQueryAsync, + wbem_services_ExecNotificationQuery, + wbem_services_ExecNotificationQueryAsync, + wbem_services_ExecMethod, + wbem_services_ExecMethodAsync +}; + +HRESULT WbemServices_create( const WCHAR *namespace, LPVOID *ppObj ) +{ + struct wbem_services *ws; + + TRACE("(%p)\n", ppObj); + + ws = heap_alloc( sizeof(*ws) ); + if (!ws) return E_OUTOFMEMORY; + + ws->IWbemServices_iface.lpVtbl = &wbem_services_vtbl; + ws->refs = 1; + ws->namespace = heap_strdupW( namespace ); + ws->async = NULL; + InitializeCriticalSection( &ws->cs ); + ws->cs.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": wbemprox_services.cs"); + + *ppObj = &ws->IWbemServices_iface; + + TRACE("returning iface %p\n", *ppObj); + return S_OK; +} diff --git a/reactos/dll/win32/wbemprox/table.c b/reactos/dll/win32/wbemprox/table.c new file mode 100644 index 00000000000..f9250204e4e --- /dev/null +++ b/reactos/dll/win32/wbemprox/table.c @@ -0,0 +1,418 @@ +/* + * Copyright 2012 Hans Leidekker for CodeWeavers + * + * 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 "wbemprox_private.h" + +#include + +HRESULT get_column_index( const struct table *table, const WCHAR *name, UINT *column ) +{ + UINT i; + for (i = 0; i < table->num_cols; i++) + { + if (!strcmpiW( table->columns[i].name, name )) + { + *column = i; + return S_OK; + } + } + return WBEM_E_INVALID_QUERY; +} + +UINT get_type_size( CIMTYPE type ) +{ + if (type & CIM_FLAG_ARRAY) return sizeof(void *); + + switch (type) + { + case CIM_BOOLEAN: + return sizeof(int); + case CIM_SINT8: + case CIM_UINT8: + return sizeof(INT8); + case CIM_SINT16: + case CIM_UINT16: + return sizeof(INT16); + case CIM_SINT32: + case CIM_UINT32: + return sizeof(INT32); + case CIM_SINT64: + case CIM_UINT64: + return sizeof(INT64); + case CIM_DATETIME: + case CIM_STRING: + return sizeof(WCHAR *); + default: + ERR("unhandled type %u\n", type); + break; + } + return sizeof(LONGLONG); +} + +static UINT get_column_size( const struct table *table, UINT column ) +{ + return get_type_size( table->columns[column].type & COL_TYPE_MASK ); +} + +static UINT get_column_offset( const struct table *table, UINT column ) +{ + UINT i, offset = 0; + for (i = 0; i < column; i++) offset += get_column_size( table, i ); + return offset; +} + +static UINT get_row_size( const struct table *table ) +{ + return get_column_offset( table, table->num_cols - 1 ) + get_column_size( table, table->num_cols - 1 ); +} + +HRESULT get_value( const struct table *table, UINT row, UINT column, LONGLONG *val ) +{ + UINT col_offset, row_size; + const BYTE *ptr; + + col_offset = get_column_offset( table, column ); + row_size = get_row_size( table ); + ptr = table->data + row * row_size + col_offset; + + if (table->columns[column].type & CIM_FLAG_ARRAY) + { + *val = (INT_PTR)*(const void **)ptr; + return S_OK; + } + switch (table->columns[column].type & COL_TYPE_MASK) + { + case CIM_BOOLEAN: + *val = *(const int *)ptr; + break; + case CIM_DATETIME: + case CIM_STRING: + *val = (INT_PTR)*(const WCHAR **)ptr; + break; + case CIM_SINT8: + *val = *(const INT8 *)ptr; + break; + case CIM_UINT8: + *val = *(const UINT8 *)ptr; + break; + case CIM_SINT16: + *val = *(const INT16 *)ptr; + break; + case CIM_UINT16: + *val = *(const UINT16 *)ptr; + break; + case CIM_SINT32: + *val = *(const INT32 *)ptr; + break; + case CIM_UINT32: + *val = *(const UINT32 *)ptr; + break; + case CIM_SINT64: + *val = *(const INT64 *)ptr; + break; + case CIM_UINT64: + *val = *(const UINT64 *)ptr; + break; + default: + ERR("invalid column type %u\n", table->columns[column].type & COL_TYPE_MASK); + *val = 0; + break; + } + return S_OK; +} + +BSTR get_value_bstr( const struct table *table, UINT row, UINT column ) +{ + static const WCHAR fmt_signedW[] = {'%','d',0}; + static const WCHAR fmt_unsignedW[] = {'%','u',0}; + static const WCHAR fmt_signed64W[] = {'%','I','6','4','d',0}; + static const WCHAR fmt_unsigned64W[] = {'%','I','6','4','u',0}; + static const WCHAR fmt_strW[] = {'\"','%','s','\"',0}; + static const WCHAR trueW[] = {'T','R','U','E',0}; + static const WCHAR falseW[] = {'F','A','L','S','E',0}; + LONGLONG val; + BSTR ret; + WCHAR number[22]; + UINT len; + + if (table->columns[column].type & CIM_FLAG_ARRAY) + { + FIXME("array to string conversion not handled\n"); + return NULL; + } + if (get_value( table, row, column, &val ) != S_OK) return NULL; + + switch (table->columns[column].type & COL_TYPE_MASK) + { + case CIM_BOOLEAN: + if (val) return SysAllocString( trueW ); + else return SysAllocString( falseW ); + + case CIM_DATETIME: + case CIM_STRING: + if (!val) return NULL; + len = strlenW( (const WCHAR *)(INT_PTR)val ) + 2; + if (!(ret = SysAllocStringLen( NULL, len ))) return NULL; + sprintfW( ret, fmt_strW, (const WCHAR *)(INT_PTR)val ); + return ret; + + case CIM_SINT16: + case CIM_SINT32: + sprintfW( number, fmt_signedW, val ); + return SysAllocString( number ); + + case CIM_UINT16: + case CIM_UINT32: + sprintfW( number, fmt_unsignedW, val ); + return SysAllocString( number ); + + case CIM_SINT64: + wsprintfW( number, fmt_signed64W, val ); + return SysAllocString( number ); + + case CIM_UINT64: + wsprintfW( number, fmt_unsigned64W, val ); + return SysAllocString( number ); + + default: + FIXME("unhandled column type %u\n", table->columns[column].type & COL_TYPE_MASK); + break; + } + return NULL; +} + +HRESULT set_value( const struct table *table, UINT row, UINT column, LONGLONG val, + CIMTYPE type ) +{ + UINT col_offset, row_size; + BYTE *ptr; + + if ((table->columns[column].type & COL_TYPE_MASK) != type) return WBEM_E_TYPE_MISMATCH; + + col_offset = get_column_offset( table, column ); + row_size = get_row_size( table ); + ptr = table->data + row * row_size + col_offset; + + switch (table->columns[column].type & COL_TYPE_MASK) + { + case CIM_DATETIME: + case CIM_STRING: + *(WCHAR **)ptr = (WCHAR *)(INT_PTR)val; + break; + case CIM_SINT8: + *(INT8 *)ptr = val; + break; + case CIM_UINT8: + *(UINT8 *)ptr = val; + break; + case CIM_SINT16: + *(INT16 *)ptr = val; + break; + case CIM_UINT16: + *(UINT16 *)ptr = val; + break; + case CIM_SINT32: + *(INT32 *)ptr = val; + break; + case CIM_UINT32: + *(UINT32 *)ptr = val; + break; + case CIM_SINT64: + *(INT64 *)ptr = val; + break; + case CIM_UINT64: + *(UINT64 *)ptr = val; + break; + default: + FIXME("unhandled column type %u\n", type); + return WBEM_E_FAILED; + } + return S_OK; +} + +HRESULT get_method( const struct table *table, const WCHAR *name, class_method **func ) +{ + UINT i, j; + + for (i = 0; i < table->num_rows; i++) + { + for (j = 0; j < table->num_cols; j++) + { + if (table->columns[j].type & COL_FLAG_METHOD && !strcmpW( table->columns[j].name, name )) + { + HRESULT hr; + LONGLONG val; + + if ((hr = get_value( table, i, j, &val )) != S_OK) return hr; + *func = (class_method *)(INT_PTR)val; + return S_OK; + } + } + } + return WBEM_E_INVALID_METHOD; + +} + +void free_row_values( const struct table *table, UINT row ) +{ + UINT i, type; + LONGLONG val; + + for (i = 0; i < table->num_cols; i++) + { + if (!(table->columns[i].type & COL_FLAG_DYNAMIC)) continue; + + type = table->columns[i].type & COL_TYPE_MASK; + if (type == CIM_STRING || type == CIM_DATETIME) + { + if (get_value( table, row, i, &val ) == S_OK) heap_free( (void *)(INT_PTR)val ); + } + else if (type & CIM_FLAG_ARRAY) + { + if (get_value( table, row, i, &val ) == S_OK) + destroy_array( (void *)(INT_PTR)val, type & CIM_TYPE_MASK ); + } + } +} + +void clear_table( struct table *table ) +{ + UINT i; + + if (!table->data) return; + + for (i = 0; i < table->num_rows; i++) free_row_values( table, i ); + if (table->fill) + { + table->num_rows = 0; + table->num_rows_allocated = 0; + heap_free( table->data ); + table->data = NULL; + } +} + +void free_columns( struct column *columns, UINT num_cols ) +{ + UINT i; + + for (i = 0; i < num_cols; i++) { heap_free( (WCHAR *)columns[i].name ); } + heap_free( columns ); +} + +void free_table( struct table *table ) +{ + if (!table) return; + + clear_table( table ); + if (table->flags & TABLE_FLAG_DYNAMIC) + { + TRACE("destroying %p\n", table); + heap_free( (WCHAR *)table->name ); + free_columns( (struct column *)table->columns, table->num_cols ); + list_remove( &table->entry ); + heap_free( table ); + } +} + +void release_table( struct table *table ) +{ + if (!InterlockedDecrement( &table->refs )) free_table( table ); +} + +struct table *addref_table( struct table *table ) +{ + InterlockedIncrement( &table->refs ); + return table; +} + +struct table *grab_table( const WCHAR *name ) +{ + struct table *table; + + LIST_FOR_EACH_ENTRY( table, table_list, struct table, entry ) + { + if (!strcmpiW( table->name, name )) + { + TRACE("returning %p\n", table); + return addref_table( table ); + } + } + return NULL; +} + +struct table *create_table( const WCHAR *name, UINT num_cols, const struct column *columns, + UINT num_rows, UINT num_allocated, BYTE *data, + enum fill_status (*fill)(struct table *, const struct expr *cond) ) +{ + struct table *table; + + if (!(table = heap_alloc( sizeof(*table) ))) return NULL; + table->name = heap_strdupW( name ); + table->num_cols = num_cols; + table->columns = columns; + table->num_rows = num_rows; + table->num_rows_allocated = num_allocated; + table->data = data; + table->fill = fill; + table->flags = TABLE_FLAG_DYNAMIC; + table->refs = 0; + list_init( &table->entry ); + return table; +} + +BOOL add_table( struct table *table ) +{ + struct table *iter; + + LIST_FOR_EACH_ENTRY( iter, table_list, struct table, entry ) + { + if (!strcmpiW( iter->name, table->name )) + { + TRACE("table %s already exists\n", debugstr_w(table->name)); + return FALSE; + } + } + list_add_tail( table_list, &table->entry ); + TRACE("added %p\n", table); + return TRUE; +} + +BSTR get_method_name( const WCHAR *class, UINT index ) +{ + struct table *table; + UINT i, count = 0; + BSTR ret; + + if (!(table = grab_table( class ))) return NULL; + + for (i = 0; i < table->num_cols; i++) + { + if (table->columns[i].type & COL_FLAG_METHOD) + { + if (index == count) + { + ret = SysAllocString( table->columns[i].name ); + release_table( table ); + return ret; + } + count++; + } + } + release_table( table ); + return NULL; +} diff --git a/reactos/dll/win32/wbemprox/wbemlocator.c b/reactos/dll/win32/wbemprox/wbemlocator.c new file mode 100644 index 00000000000..36eba950255 --- /dev/null +++ b/reactos/dll/win32/wbemprox/wbemlocator.c @@ -0,0 +1,217 @@ +/* + * Copyright 2009 Hans Leidekker for CodeWeavers + * + * 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 "wbemprox_private.h" + +typedef struct +{ + IWbemLocator IWbemLocator_iface; + LONG refs; +} wbem_locator; + +static inline wbem_locator *impl_from_IWbemLocator( IWbemLocator *iface ) +{ + return CONTAINING_RECORD(iface, wbem_locator, IWbemLocator_iface); +} + +static ULONG WINAPI wbem_locator_AddRef( + IWbemLocator *iface ) +{ + wbem_locator *wl = impl_from_IWbemLocator( iface ); + return InterlockedIncrement( &wl->refs ); +} + +static ULONG WINAPI wbem_locator_Release( + IWbemLocator *iface ) +{ + wbem_locator *wl = impl_from_IWbemLocator( iface ); + LONG refs = InterlockedDecrement( &wl->refs ); + if (!refs) + { + TRACE("destroying %p\n", wl); + heap_free( wl ); + } + return refs; +} + +static HRESULT WINAPI wbem_locator_QueryInterface( + IWbemLocator *iface, + REFIID riid, + void **ppvObject ) +{ + wbem_locator *This = impl_from_IWbemLocator( iface ); + + TRACE("%p %s %p\n", This, debugstr_guid( riid ), ppvObject ); + + if ( IsEqualGUID( riid, &IID_IWbemLocator ) || + IsEqualGUID( riid, &IID_IUnknown ) ) + { + *ppvObject = iface; + } + else + { + FIXME("interface %s not implemented\n", debugstr_guid(riid)); + return E_NOINTERFACE; + } + IWbemLocator_AddRef( iface ); + return S_OK; +} + +static BOOL is_local_machine( const WCHAR *server ) +{ + static const WCHAR dotW[] = {'.',0}; + static const WCHAR localhostW[] = {'l','o','c','a','l','h','o','s','t',0}; + WCHAR buffer[MAX_COMPUTERNAME_LENGTH + 1]; + DWORD len = sizeof(buffer) / sizeof(buffer[0]); + + if (!server || !strcmpW( server, dotW ) || !strcmpiW( server, localhostW )) return TRUE; + if (GetComputerNameW( buffer, &len ) && !strcmpiW( server, buffer )) return TRUE; + return FALSE; +} + +static HRESULT parse_resource( const WCHAR *resource, WCHAR **server, WCHAR **namespace ) +{ + static const WCHAR rootW[] = {'R','O','O','T'}; + static const WCHAR cimv2W[] = {'C','I','M','V','2'}; + static const WCHAR defaultW[] = {'D','E','F','A','U','L','T'}; + HRESULT hr = WBEM_E_INVALID_NAMESPACE; + const WCHAR *p, *q; + unsigned int len; + + *server = NULL; + *namespace = NULL; + p = q = resource; + if (*p == '\\' || *p == '/') + { + p++; + if (*p == '\\' || *p == '/') p++; + if (!*p) return WBEM_E_INVALID_NAMESPACE; + if (*p == '\\' || *p == '/') return WBEM_E_INVALID_PARAMETER; + q = p + 1; + while (*q && *q != '\\' && *q != '/') q++; + if (!*q) return WBEM_E_INVALID_NAMESPACE; + len = q - p; + if (!(*server = heap_alloc( (len + 1) * sizeof(WCHAR) ))) + { + hr = E_OUTOFMEMORY; + goto done; + } + memcpy( *server, p, len * sizeof(WCHAR) ); + (*server)[len] = 0; + q++; + } + if (!*q) goto done; + p = q; + while (*q && *q != '\\' && *q != '/') q++; + len = q - p; + if (len >= sizeof(rootW) / sizeof(rootW[0]) && memicmpW( rootW, p, len )) goto done; + if (!*q) + { + hr = S_OK; + goto done; + } + q++; + len = strlenW( q ); + if ((len != sizeof(cimv2W) / sizeof(cimv2W[0]) || memicmpW( q, cimv2W, len )) && + (len != sizeof(defaultW) / sizeof(defaultW[0]) || memicmpW( q, defaultW, len ))) + goto done; + if (!(*namespace = heap_alloc( (len + 1) * sizeof(WCHAR) ))) hr = E_OUTOFMEMORY; + else + { + memcpy( *namespace, p, len * sizeof(WCHAR) ); + (*namespace)[len] = 0; + hr = S_OK; + } + +done: + if (hr != S_OK) + { + heap_free( *server ); + heap_free( *namespace ); + } + return hr; +} + +static HRESULT WINAPI wbem_locator_ConnectServer( + IWbemLocator *iface, + const BSTR NetworkResource, + const BSTR User, + const BSTR Password, + const BSTR Locale, + LONG SecurityFlags, + const BSTR Authority, + IWbemContext *pCtx, + IWbemServices **ppNamespace) +{ + HRESULT hr; + WCHAR *server, *namespace; + + TRACE("%p, %s, %s, %s, %s, 0x%08x, %s, %p, %p)\n", iface, debugstr_w(NetworkResource), debugstr_w(User), + debugstr_w(Password), debugstr_w(Locale), SecurityFlags, debugstr_w(Authority), pCtx, ppNamespace); + + hr = parse_resource( NetworkResource, &server, &namespace ); + if (hr != S_OK) return hr; + + if (!is_local_machine( server )) + { + FIXME("remote computer not supported\n"); + heap_free( server ); + heap_free( namespace ); + return WBEM_E_TRANSPORT_FAILURE; + } + if (User || Password || Authority) + FIXME("authentication not supported\n"); + if (Locale) + FIXME("specific locale not supported\n"); + if (SecurityFlags) + FIXME("unsupported flags\n"); + + hr = WbemServices_create( namespace, (void **)ppNamespace ); + heap_free( namespace ); + heap_free( server ); + if (SUCCEEDED( hr )) + return WBEM_NO_ERROR; + + return WBEM_E_FAILED; +} + +static const IWbemLocatorVtbl wbem_locator_vtbl = +{ + wbem_locator_QueryInterface, + wbem_locator_AddRef, + wbem_locator_Release, + wbem_locator_ConnectServer +}; + +HRESULT WbemLocator_create( LPVOID *ppObj ) +{ + wbem_locator *wl; + + TRACE("(%p)\n", ppObj); + + wl = heap_alloc( sizeof(*wl) ); + if (!wl) return E_OUTOFMEMORY; + + wl->IWbemLocator_iface.lpVtbl = &wbem_locator_vtbl; + wl->refs = 1; + + *ppObj = &wl->IWbemLocator_iface; + + TRACE("returning iface %p\n", *ppObj); + return S_OK; +} diff --git a/reactos/dll/win32/wbemprox/wbemprox.idl b/reactos/dll/win32/wbemprox/wbemprox.idl new file mode 100644 index 00000000000..5c6255a39dc --- /dev/null +++ b/reactos/dll/win32/wbemprox/wbemprox.idl @@ -0,0 +1,35 @@ +/* + * COM Classes for wbemprox + * + * Copyright 2010 Alexandre Julliard + * + * 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 + */ + +#pragma makedep register + +[ + helpstring("WBEM Locator"), + threading(both), + uuid(4590f811-1d3a-11d0-891f-00aa004b2e24) +] +coclass WbemLocator { interface IWbemLocator; } + +[ + helpstring("WBEM Administrative Locator"), + threading(both), + uuid(cb8555cc-9128-11d1-ad9b-00c04fd8fdff) +] +coclass WbemAdministrativeLocator { interface IWbemLocator; } diff --git a/reactos/dll/win32/wbemprox/wbemprox.rc b/reactos/dll/win32/wbemprox/wbemprox.rc new file mode 100644 index 00000000000..b3d5c433d3b --- /dev/null +++ b/reactos/dll/win32/wbemprox/wbemprox.rc @@ -0,0 +1 @@ +1 WINE_REGISTRY "wbemprox.rgs" diff --git a/reactos/dll/win32/wbemprox/wbemprox.rgs b/reactos/dll/win32/wbemprox/wbemprox.rgs new file mode 100644 index 00000000000..7982412679b --- /dev/null +++ b/reactos/dll/win32/wbemprox/wbemprox.rgs @@ -0,0 +1,17 @@ +HKCR +{ + NoRemove Interface + { + } + NoRemove CLSID + { + '{4590F811-1D3A-11D0-891F-00AA004B2E24}' = s 'WBEM Locator' + { + InprocServer32 = s '%MODULE%' { val ThreadingModel = s 'Both' } + } + '{CB8555CC-9128-11D1-AD9B-00C04FD8FDFF}' = s 'WBEM Administrative Locator' + { + InprocServer32 = s '%MODULE%' { val ThreadingModel = s 'Both' } + } + } +} diff --git a/reactos/dll/win32/wbemprox/wbemprox.spec b/reactos/dll/win32/wbemprox/wbemprox.spec new file mode 100644 index 00000000000..b16365d0c9f --- /dev/null +++ b/reactos/dll/win32/wbemprox/wbemprox.spec @@ -0,0 +1,4 @@ +@ stdcall -private DllCanUnloadNow() +@ stdcall -private DllGetClassObject(ptr ptr ptr) +@ stdcall -private DllRegisterServer() +@ stdcall -private DllUnregisterServer() diff --git a/reactos/dll/win32/wbemprox/wbemprox_private.h b/reactos/dll/win32/wbemprox/wbemprox_private.h new file mode 100644 index 00000000000..36508c94fb8 --- /dev/null +++ b/reactos/dll/win32/wbemprox/wbemprox_private.h @@ -0,0 +1,315 @@ +/* + * Copyright 2009 Hans Leidekker for CodeWeavers + * + * 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 + */ + +#ifndef _WBEMPROX_PRIVATE_H_ +#define _WBEMPROX_PRIVATE_H_ + +#include + +#include + +#define _INC_WINDOWS +#define COM_NO_WINDOWS_H + +#define COBJMACROS +#define NONAMELESSUNION +#define NONAMELESSSTRUCT + +#include +#define WIN32_NO_STATUS +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +WINE_DEFAULT_DEBUG_CHANNEL(wbemprox); + +IClientSecurity client_security DECLSPEC_HIDDEN; +struct list *table_list DECLSPEC_HIDDEN; + +#define SIZEOF(array) (sizeof(array)/sizeof((array)[0])) + +enum param_direction +{ + PARAM_OUT = -1, + PARAM_INOUT = 0, + PARAM_IN = 1 +}; + +#define CIM_TYPE_MASK 0x00000fff + +#define COL_TYPE_MASK 0x0000ffff +#define COL_FLAG_DYNAMIC 0x00010000 +#define COL_FLAG_KEY 0x00020000 +#define COL_FLAG_METHOD 0x00040000 + +typedef HRESULT (class_method)(IWbemClassObject *, IWbemClassObject *, IWbemClassObject **); + +enum operator +{ + OP_EQ = 1, + OP_AND = 2, + OP_OR = 3, + OP_GT = 4, + OP_LT = 5, + OP_LE = 6, + OP_GE = 7, + OP_NE = 8, + OP_ISNULL = 9, + OP_NOTNULL = 10, + OP_LIKE = 11, + OP_NOT = 12 +}; + +struct expr; +struct complex_expr +{ + enum operator op; + struct expr *left; + struct expr *right; +}; + +enum expr_type +{ + EXPR_COMPLEX = 1, + EXPR_UNARY = 2, + EXPR_PROPVAL = 3, + EXPR_SVAL = 4, + EXPR_IVAL = 5, + EXPR_BVAL = 6 +}; + +struct expr +{ + enum expr_type type; + union + { + struct complex_expr expr; + const struct property *propval; + const WCHAR *sval; + int ival; + } u; +}; + +struct column +{ + const WCHAR *name; + UINT type; + VARTYPE vartype; /* 0 for default mapping */ +}; + +enum fill_status +{ + FILL_STATUS_FAILED = -1, + FILL_STATUS_UNFILTERED, + FILL_STATUS_FILTERED +}; + +#define TABLE_FLAG_DYNAMIC 0x00000001 + +struct table +{ + const WCHAR *name; + UINT num_cols; + const struct column *columns; + UINT num_rows; + UINT num_rows_allocated; + BYTE *data; + enum fill_status (*fill)(struct table *, const struct expr *cond); + UINT flags; + struct list entry; + LONG refs; +}; + +struct property +{ + const WCHAR *name; + const WCHAR *class; + const struct property *next; +}; + +struct array +{ + UINT count; + void *ptr; +}; + +struct field +{ + UINT type; + VARTYPE vartype; /* 0 for default mapping */ + union + { + LONGLONG ival; + WCHAR *sval; + struct array *aval; + } u; +}; + +struct record +{ + UINT count; + struct field *fields; + struct table *table; +}; + +struct view +{ + const struct property *proplist; + struct table *table; + const struct expr *cond; + UINT *result; + UINT count; +}; + +struct query +{ + LONG refs; + struct view *view; + struct list mem; +}; + +struct query *create_query(void) DECLSPEC_HIDDEN; +void free_query( struct query * ) DECLSPEC_HIDDEN; +struct query *addref_query( struct query * ) DECLSPEC_HIDDEN; +void release_query( struct query *query ) DECLSPEC_HIDDEN; +HRESULT exec_query( const WCHAR *, IEnumWbemClassObject ** ) DECLSPEC_HIDDEN; +HRESULT parse_query( const WCHAR *, struct view **, struct list * ) DECLSPEC_HIDDEN; +HRESULT create_view( const struct property *, const WCHAR *, const struct expr *, + struct view ** ) DECLSPEC_HIDDEN; +void destroy_view( struct view * ) DECLSPEC_HIDDEN; +HRESULT execute_view( struct view * ) DECLSPEC_HIDDEN; +void init_table_list( void ) DECLSPEC_HIDDEN; +struct table *grab_table( const WCHAR * ) DECLSPEC_HIDDEN; +struct table *addref_table( struct table * ) DECLSPEC_HIDDEN; +void release_table( struct table * ) DECLSPEC_HIDDEN; +struct table *create_table( const WCHAR *, UINT, const struct column *, UINT, UINT, BYTE *, + enum fill_status (*)(struct table *, const struct expr *) ) DECLSPEC_HIDDEN; +BOOL add_table( struct table * ) DECLSPEC_HIDDEN; +void free_columns( struct column *, UINT ) DECLSPEC_HIDDEN; +void free_row_values( const struct table *, UINT ) DECLSPEC_HIDDEN; +void clear_table( struct table * ) DECLSPEC_HIDDEN; +void free_table( struct table * ) DECLSPEC_HIDDEN; +UINT get_type_size( CIMTYPE ) DECLSPEC_HIDDEN; +HRESULT eval_cond( const struct table *, UINT, const struct expr *, LONGLONG *, UINT * ) DECLSPEC_HIDDEN; +HRESULT get_column_index( const struct table *, const WCHAR *, UINT * ) DECLSPEC_HIDDEN; +HRESULT get_value( const struct table *, UINT, UINT, LONGLONG * ) DECLSPEC_HIDDEN; +BSTR get_value_bstr( const struct table *, UINT, UINT ) DECLSPEC_HIDDEN; +HRESULT set_value( const struct table *, UINT, UINT, LONGLONG, CIMTYPE ) DECLSPEC_HIDDEN; +BOOL is_method( const struct table *, UINT ) DECLSPEC_HIDDEN; +HRESULT get_method( const struct table *, const WCHAR *, class_method ** ) DECLSPEC_HIDDEN; +HRESULT get_propval( const struct view *, UINT, const WCHAR *, VARIANT *, + CIMTYPE *, LONG * ) DECLSPEC_HIDDEN; +HRESULT put_propval( const struct view *, UINT, const WCHAR *, VARIANT *, CIMTYPE ) DECLSPEC_HIDDEN; +HRESULT to_longlong( VARIANT *, LONGLONG *, CIMTYPE * ) DECLSPEC_HIDDEN; +SAFEARRAY *to_safearray( const struct array *, CIMTYPE ) DECLSPEC_HIDDEN; +VARTYPE to_vartype( CIMTYPE ) DECLSPEC_HIDDEN; +void destroy_array( struct array *, CIMTYPE ) DECLSPEC_HIDDEN; +BOOL is_selected_prop( const struct view *, const WCHAR * ) DECLSPEC_HIDDEN; +HRESULT get_properties( const struct view *, LONG, SAFEARRAY ** ) DECLSPEC_HIDDEN; +HRESULT get_object( const WCHAR *, IWbemClassObject ** ) DECLSPEC_HIDDEN; +BSTR get_method_name( const WCHAR *, UINT ) DECLSPEC_HIDDEN; +void set_variant( VARTYPE, LONGLONG, void *, VARIANT * ) DECLSPEC_HIDDEN; +HRESULT create_signature( const WCHAR *, const WCHAR *, enum param_direction, + IWbemClassObject ** ) DECLSPEC_HIDDEN; + +HRESULT WbemLocator_create(LPVOID *) DECLSPEC_HIDDEN; +HRESULT WbemServices_create(const WCHAR *, LPVOID *) DECLSPEC_HIDDEN; +HRESULT create_class_object(const WCHAR *, IEnumWbemClassObject *, UINT, + struct record *, IWbemClassObject **) DECLSPEC_HIDDEN; +HRESULT EnumWbemClassObject_create(struct query *, LPVOID *) DECLSPEC_HIDDEN; +HRESULT WbemQualifierSet_create(const WCHAR *, const WCHAR *, LPVOID *) DECLSPEC_HIDDEN; + +HRESULT process_get_owner(IWbemClassObject *, IWbemClassObject *, IWbemClassObject **) DECLSPEC_HIDDEN; +HRESULT reg_enum_key(IWbemClassObject *, IWbemClassObject *, IWbemClassObject **) DECLSPEC_HIDDEN; +HRESULT reg_enum_values(IWbemClassObject *, IWbemClassObject *, IWbemClassObject **) DECLSPEC_HIDDEN; +HRESULT reg_get_stringvalue(IWbemClassObject *, IWbemClassObject *, IWbemClassObject **) DECLSPEC_HIDDEN; +HRESULT service_pause_service(IWbemClassObject *, IWbemClassObject *, IWbemClassObject **) DECLSPEC_HIDDEN; +HRESULT service_resume_service(IWbemClassObject *, IWbemClassObject *, IWbemClassObject **) DECLSPEC_HIDDEN; +HRESULT service_start_service(IWbemClassObject *, IWbemClassObject *, IWbemClassObject **) DECLSPEC_HIDDEN; +HRESULT service_stop_service(IWbemClassObject *, IWbemClassObject *, IWbemClassObject **) DECLSPEC_HIDDEN; +HRESULT security_get_sd(IWbemClassObject *, IWbemClassObject *, IWbemClassObject **) DECLSPEC_HIDDEN; +HRESULT security_set_sd(IWbemClassObject *, IWbemClassObject *, IWbemClassObject **) DECLSPEC_HIDDEN; + +static void *heap_alloc( size_t len ) __WINE_ALLOC_SIZE(1); +static inline void *heap_alloc( size_t len ) +{ + return HeapAlloc( GetProcessHeap(), 0, len ); +} + +static void *heap_realloc( void *mem, size_t len ) __WINE_ALLOC_SIZE(2); +static inline void *heap_realloc( void *mem, size_t len ) +{ + return HeapReAlloc( GetProcessHeap(), 0, mem, len ); +} + +static void *heap_alloc_zero( size_t len ) __WINE_ALLOC_SIZE(1); +static inline void *heap_alloc_zero( size_t len ) +{ + return HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, len ); +} + +static inline BOOL heap_free( void *mem ) +{ + return HeapFree( GetProcessHeap(), 0, mem ); +} + +static inline WCHAR *heap_strdupW( const WCHAR *src ) +{ + WCHAR *dst; + if (!src) return NULL; + if ((dst = heap_alloc( (strlenW( src ) + 1) * sizeof(WCHAR) ))) strcpyW( dst, src ); + return dst; +} + +static const WCHAR class_processW[] = {'W','i','n','3','2','_','P','r','o','c','e','s','s',0}; +static const WCHAR class_serviceW[] = {'W','i','n','3','2','_','S','e','r','v','i','c','e',0}; +static const WCHAR class_stdregprovW[] = {'S','t','d','R','e','g','P','r','o','v',0}; +static const WCHAR class_systemsecurityW[] = {'_','_','S','y','s','t','e','m','S','e','c','u','r','i','t','y',0}; + +static const WCHAR prop_nameW[] = {'N','a','m','e',0}; + +static const WCHAR method_enumkeyW[] = {'E','n','u','m','K','e','y',0}; +static const WCHAR method_enumvaluesW[] = {'E','n','u','m','V','a','l','u','e','s',0}; +static const WCHAR method_getownerW[] = {'G','e','t','O','w','n','e','r',0}; +static const WCHAR method_getsdW[] = {'G','e','t','S','D',0}; +static const WCHAR method_getstringvalueW[] = {'G','e','t','S','t','r','i','n','g','V','a','l','u','e',0}; +static const WCHAR method_pauseserviceW[] = {'P','a','u','s','e','S','e','r','v','i','c','e',0}; +static const WCHAR method_resumeserviceW[] = {'R','e','s','u','m','e','S','e','r','v','i','c','e',0}; +static const WCHAR method_setsdW[] = {'S','e','t','S','D',0}; +static const WCHAR method_startserviceW[] = {'S','t','a','r','t','S','e','r','v','i','c','e',0}; +static const WCHAR method_stopserviceW[] = {'S','t','o','p','S','e','r','v','i','c','e',0}; + +static const WCHAR param_defkeyW[] = {'h','D','e','f','K','e','y',0}; +static const WCHAR param_domainW[] = {'D','o','m','a','i','n',0}; +static const WCHAR param_namesW[] = {'s','N','a','m','e','s',0}; +static const WCHAR param_returnvalueW[] = {'R','e','t','u','r','n','V','a','l','u','e',0}; +static const WCHAR param_sdW[] = {'S','D',0}; +static const WCHAR param_subkeynameW[] = {'s','S','u','b','K','e','y','N','a','m','e',0}; +static const WCHAR param_typesW[] = {'T','y','p','e','s',0}; +static const WCHAR param_userW[] = {'U','s','e','r',0}; +static const WCHAR param_valueW[] = {'s','V','a','l','u','e',0}; +static const WCHAR param_valuenameW[] = {'s','V','a','l','u','e','N','a','m','e',0}; + +#endif /* _WBEMPROX_PRIVATE_H_ */ diff --git a/reactos/dll/win32/wbemprox/wql.tab.c b/reactos/dll/win32/wbemprox/wql.tab.c new file mode 100644 index 00000000000..91b7ac46bfc --- /dev/null +++ b/reactos/dll/win32/wbemprox/wql.tab.c @@ -0,0 +1,2275 @@ +/* A Bison parser, made by GNU Bison 3.0.2. */ + +/* Bison implementation for Yacc-like parsers in C + + Copyright (C) 1984, 1989-1990, 2000-2013 Free Software Foundation, Inc. + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ + +/* As a special exception, you may create a larger work that contains + part or all of the Bison parser skeleton and distribute that work + under terms of your choice, so long as that work isn't itself a + parser generator using the skeleton or a modified version thereof + as a parser skeleton. Alternatively, if you modify or redistribute + the parser skeleton itself, you may (at your option) remove this + special exception, which will cause the skeleton and the resulting + Bison output files to be licensed under the GNU General Public + License without this special exception. + + This special exception was added by the Free Software Foundation in + version 2.2 of Bison. */ + +/* C LALR(1) parser skeleton written by Richard Stallman, by + simplifying the original so-called "semantic" parser. */ + +/* All symbols defined below should begin with yy or YY, to avoid + infringing on user name space. This should be done even for local + variables, as they might otherwise be expanded by user macros. + There are some unavoidable exceptions within include files to + define necessary library symbols; they are noted "INFRINGES ON + USER NAME SPACE" below. */ + +/* Identify Bison output. */ +#define YYBISON 1 + +/* Bison version. */ +#define YYBISON_VERSION "3.0.2" + +/* Skeleton name. */ +#define YYSKELETON_NAME "yacc.c" + +/* Pure parsers. */ +#define YYPURE 1 + +/* Push parsers. */ +#define YYPUSH 0 + +/* Pull parsers. */ +#define YYPULL 1 + + +/* Substitute the variable and function names. */ +#define yyparse wql_parse +#define yylex wql_lex +#define yyerror wql_error +#define yydebug wql_debug +#define yynerrs wql_nerrs + + +/* Copy the first part of user declarations. */ +#line 1 "wql.y" /* yacc.c:339 */ + + +/* + * Copyright 2012 Hans Leidekker for CodeWeavers + * + * 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 "wbemprox_private.h" + +struct parser +{ + const WCHAR *cmd; + UINT idx; + UINT len; + HRESULT error; + struct view **view; + struct list *mem; +}; + +struct string +{ + const WCHAR *data; + int len; +}; + +static void *alloc_mem( struct parser *parser, UINT size ) +{ + struct list *mem = heap_alloc( sizeof(struct list) + size ); + list_add_tail( parser->mem, mem ); + return &mem[1]; +} + +static struct property *alloc_property( struct parser *parser, const WCHAR *class, const WCHAR *name ) +{ + struct property *prop = alloc_mem( parser, sizeof(*prop) ); + if (prop) + { + prop->name = name; + prop->class = class; + prop->next = NULL; + } + return prop; +} + +static WCHAR *get_string( struct parser *parser, const struct string *str ) +{ + const WCHAR *p = str->data; + int len = str->len; + WCHAR *ret; + + if ((p[0] == '\"' && p[len - 1] != '\"') || + (p[0] == '\'' && p[len - 1] != '\'')) return NULL; + if ((p[0] == '\"' && p[len - 1] == '\"') || + (p[0] == '\'' && p[len - 1] == '\'')) + { + p++; + len -= 2; + } + if (!(ret = alloc_mem( parser, (len + 1) * sizeof(WCHAR) ))) return NULL; + memcpy( ret, p, len * sizeof(WCHAR) ); + ret[len] = 0; + return ret; +} + +static int get_int( struct parser *parser ) +{ + const WCHAR *p = &parser->cmd[parser->idx]; + int i, ret = 0; + + for (i = 0; i < parser->len; i++) + { + if (p[i] < '0' || p[i] > '9') + { + ERR("should only be numbers here!\n"); + break; + } + ret = (p[i] - '0') + ret * 10; + } + return ret; +} + +static struct expr *expr_complex( struct parser *parser, struct expr *l, UINT op, struct expr *r ) +{ + struct expr *e = alloc_mem( parser, sizeof(*e) ); + if (e) + { + e->type = EXPR_COMPLEX; + e->u.expr.left = l; + e->u.expr.op = op; + e->u.expr.right = r; + } + return e; +} + +static struct expr *expr_unary( struct parser *parser, struct expr *l, UINT op ) +{ + struct expr *e = alloc_mem( parser, sizeof(*e) ); + if (e) + { + e->type = EXPR_UNARY; + e->u.expr.left = l; + e->u.expr.op = op; + e->u.expr.right = NULL; + } + return e; +} + +static struct expr *expr_ival( struct parser *parser, int val ) +{ + struct expr *e = alloc_mem( parser, sizeof *e ); + if (e) + { + e->type = EXPR_IVAL; + e->u.ival = val; + } + return e; +} + +static struct expr *expr_sval( struct parser *parser, const struct string *str ) +{ + struct expr *e = alloc_mem( parser, sizeof *e ); + if (e) + { + e->type = EXPR_SVAL; + e->u.sval = get_string( parser, str ); + if (!e->u.sval) + return NULL; /* e will be freed by query destructor */ + } + return e; +} + +static struct expr *expr_bval( struct parser *parser, int val ) +{ + struct expr *e = alloc_mem( parser, sizeof *e ); + if (e) + { + e->type = EXPR_BVAL; + e->u.ival = val; + } + return e; +} + +static struct expr *expr_propval( struct parser *parser, const struct property *prop ) +{ + struct expr *e = alloc_mem( parser, sizeof *e ); + if (e) + { + e->type = EXPR_PROPVAL; + e->u.propval = prop; + } + return e; +} + +static int wql_error( struct parser *parser, const char *str ); +static int wql_lex( void *val, struct parser *parser ); + +#define PARSER_BUBBLE_UP_VIEW( parser, result, current_view ) \ + *parser->view = current_view; \ + result = current_view + + +#line 259 "wql.tab.c" /* yacc.c:339 */ + +# ifndef YY_NULLPTR +# if defined __cplusplus && 201103L <= __cplusplus +# define YY_NULLPTR nullptr +# else +# define YY_NULLPTR 0 +# endif +# endif + +/* Enabling verbose error messages. */ +#ifdef YYERROR_VERBOSE +# undef YYERROR_VERBOSE +# define YYERROR_VERBOSE 1 +#else +# define YYERROR_VERBOSE 1 +#endif + + +/* Debug traces. */ +#ifndef YYDEBUG +# define YYDEBUG 0 +#endif +#if YYDEBUG +extern int wql_debug; +#endif + +/* Token type. */ +#ifndef YYTOKENTYPE +# define YYTOKENTYPE + enum yytokentype + { + TK_SELECT = 258, + TK_FROM = 259, + TK_STAR = 260, + TK_COMMA = 261, + TK_DOT = 262, + TK_IS = 263, + TK_LP = 264, + TK_RP = 265, + TK_NULL = 266, + TK_FALSE = 267, + TK_TRUE = 268, + TK_INTEGER = 269, + TK_WHERE = 270, + TK_SPACE = 271, + TK_MINUS = 272, + TK_ILLEGAL = 273, + TK_BY = 274, + TK_STRING = 275, + TK_ID = 276, + TK_OR = 277, + TK_AND = 278, + TK_NOT = 279, + TK_EQ = 280, + TK_NE = 281, + TK_LT = 282, + TK_GT = 283, + TK_LE = 284, + TK_GE = 285, + TK_LIKE = 286 + }; +#endif + +/* Value type. */ +#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED +typedef union YYSTYPE YYSTYPE; +union YYSTYPE +{ +#line 194 "wql.y" /* yacc.c:355 */ + + struct string str; + WCHAR *string; + struct property *proplist; + struct view *view; + struct expr *expr; + int integer; + +#line 337 "wql.tab.c" /* yacc.c:355 */ +}; +# define YYSTYPE_IS_TRIVIAL 1 +# define YYSTYPE_IS_DECLARED 1 +#endif + + + +int wql_parse (struct parser *ctx); + + + +/* Copy the second part of user declarations. */ + +#line 351 "wql.tab.c" /* yacc.c:358 */ + +#ifdef short +# undef short +#endif + +#ifdef YYTYPE_UINT8 +typedef YYTYPE_UINT8 yytype_uint8; +#else +typedef unsigned char yytype_uint8; +#endif + +#ifdef YYTYPE_INT8 +typedef YYTYPE_INT8 yytype_int8; +#else +typedef signed char yytype_int8; +#endif + +#ifdef YYTYPE_UINT16 +typedef YYTYPE_UINT16 yytype_uint16; +#else +typedef unsigned short int yytype_uint16; +#endif + +#ifdef YYTYPE_INT16 +typedef YYTYPE_INT16 yytype_int16; +#else +typedef short int yytype_int16; +#endif + +#ifndef YYSIZE_T +# ifdef __SIZE_TYPE__ +# define YYSIZE_T __SIZE_TYPE__ +# elif defined size_t +# define YYSIZE_T size_t +# elif ! defined YYSIZE_T +# include /* INFRINGES ON USER NAME SPACE */ +# define YYSIZE_T size_t +# else +# define YYSIZE_T unsigned int +# endif +#endif + +#define YYSIZE_MAXIMUM ((YYSIZE_T) -1) + +#ifndef YY_ +# if defined YYENABLE_NLS && YYENABLE_NLS +# if ENABLE_NLS +# include /* INFRINGES ON USER NAME SPACE */ +# define YY_(Msgid) dgettext ("bison-runtime", Msgid) +# endif +# endif +# ifndef YY_ +# define YY_(Msgid) Msgid +# endif +#endif + +#ifndef YY_ATTRIBUTE +# if (defined __GNUC__ \ + && (2 < __GNUC__ || (__GNUC__ == 2 && 96 <= __GNUC_MINOR__))) \ + || defined __SUNPRO_C && 0x5110 <= __SUNPRO_C +# define YY_ATTRIBUTE(Spec) __attribute__(Spec) +# else +# define YY_ATTRIBUTE(Spec) /* empty */ +# endif +#endif + +#ifndef YY_ATTRIBUTE_PURE +# define YY_ATTRIBUTE_PURE YY_ATTRIBUTE ((__pure__)) +#endif + +#ifndef YY_ATTRIBUTE_UNUSED +# define YY_ATTRIBUTE_UNUSED YY_ATTRIBUTE ((__unused__)) +#endif + +#if !defined _Noreturn \ + && (!defined __STDC_VERSION__ || __STDC_VERSION__ < 201112) +# if defined _MSC_VER && 1200 <= _MSC_VER +# define _Noreturn __declspec (noreturn) +# else +# define _Noreturn YY_ATTRIBUTE ((__noreturn__)) +# endif +#endif + +/* Suppress unused-variable warnings by "using" E. */ +#if ! defined lint || defined __GNUC__ +# define YYUSE(E) ((void) (E)) +#else +# define YYUSE(E) /* empty */ +#endif + +#if defined __GNUC__ && 407 <= __GNUC__ * 100 + __GNUC_MINOR__ +/* Suppress an incorrect diagnostic about yylval being uninitialized. */ +# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN \ + _Pragma ("GCC diagnostic push") \ + _Pragma ("GCC diagnostic ignored \"-Wuninitialized\"")\ + _Pragma ("GCC diagnostic ignored \"-Wmaybe-uninitialized\"") +# define YY_IGNORE_MAYBE_UNINITIALIZED_END \ + _Pragma ("GCC diagnostic pop") +#else +# define YY_INITIAL_VALUE(Value) Value +#endif +#ifndef YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN +# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN +# define YY_IGNORE_MAYBE_UNINITIALIZED_END +#endif +#ifndef YY_INITIAL_VALUE +# define YY_INITIAL_VALUE(Value) /* Nothing. */ +#endif + + +#if ! defined yyoverflow || YYERROR_VERBOSE + +/* The parser invokes alloca or malloc; define the necessary symbols. */ + +# ifdef YYSTACK_USE_ALLOCA +# if YYSTACK_USE_ALLOCA +# ifdef __GNUC__ +# define YYSTACK_ALLOC __builtin_alloca +# elif defined __BUILTIN_VA_ARG_INCR +# include /* INFRINGES ON USER NAME SPACE */ +# elif defined _AIX +# define YYSTACK_ALLOC __alloca +# elif defined _MSC_VER +# include /* INFRINGES ON USER NAME SPACE */ +# define alloca _alloca +# else +# define YYSTACK_ALLOC alloca +# if ! defined _ALLOCA_H && ! defined EXIT_SUCCESS +# include /* INFRINGES ON USER NAME SPACE */ + /* Use EXIT_SUCCESS as a witness for stdlib.h. */ +# ifndef EXIT_SUCCESS +# define EXIT_SUCCESS 0 +# endif +# endif +# endif +# endif +# endif + +# ifdef YYSTACK_ALLOC + /* Pacify GCC's 'empty if-body' warning. */ +# define YYSTACK_FREE(Ptr) do { /* empty */; } while (0) +# ifndef YYSTACK_ALLOC_MAXIMUM + /* The OS might guarantee only one guard page at the bottom of the stack, + and a page size can be as small as 4096 bytes. So we cannot safely + invoke alloca (N) if N exceeds 4096. Use a slightly smaller number + to allow for a few compiler-allocated temporary stack slots. */ +# define YYSTACK_ALLOC_MAXIMUM 4032 /* reasonable circa 2006 */ +# endif +# else +# define YYSTACK_ALLOC YYMALLOC +# define YYSTACK_FREE YYFREE +# ifndef YYSTACK_ALLOC_MAXIMUM +# define YYSTACK_ALLOC_MAXIMUM YYSIZE_MAXIMUM +# endif +# if (defined __cplusplus && ! defined EXIT_SUCCESS \ + && ! ((defined YYMALLOC || defined malloc) \ + && (defined YYFREE || defined free))) +# include /* INFRINGES ON USER NAME SPACE */ +# ifndef EXIT_SUCCESS +# define EXIT_SUCCESS 0 +# endif +# endif +# ifndef YYMALLOC +# define YYMALLOC malloc +# if ! defined malloc && ! defined EXIT_SUCCESS +void *malloc (YYSIZE_T); /* INFRINGES ON USER NAME SPACE */ +# endif +# endif +# ifndef YYFREE +# define YYFREE free +# if ! defined free && ! defined EXIT_SUCCESS +void free (void *); /* INFRINGES ON USER NAME SPACE */ +# endif +# endif +# endif +#endif /* ! defined yyoverflow || YYERROR_VERBOSE */ + + +#if (! defined yyoverflow \ + && (! defined __cplusplus \ + || (defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL))) + +/* A type that is properly aligned for any stack member. */ +union yyalloc +{ + yytype_int16 yyss_alloc; + YYSTYPE yyvs_alloc; +}; + +/* The size of the maximum gap between one aligned stack and the next. */ +# define YYSTACK_GAP_MAXIMUM (sizeof (union yyalloc) - 1) + +/* The size of an array large to enough to hold all stacks, each with + N elements. */ +# define YYSTACK_BYTES(N) \ + ((N) * (sizeof (yytype_int16) + sizeof (YYSTYPE)) \ + + YYSTACK_GAP_MAXIMUM) + +# define YYCOPY_NEEDED 1 + +/* Relocate STACK from its old location to the new one. The + local variables YYSIZE and YYSTACKSIZE give the old and new number of + elements in the stack, and YYPTR gives the new location of the + stack. Advance YYPTR to a properly aligned location for the next + stack. */ +# define YYSTACK_RELOCATE(Stack_alloc, Stack) \ + do \ + { \ + YYSIZE_T yynewbytes; \ + YYCOPY (&yyptr->Stack_alloc, Stack, yysize); \ + Stack = &yyptr->Stack_alloc; \ + yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \ + yyptr += yynewbytes / sizeof (*yyptr); \ + } \ + while (0) + +#endif + +#if defined YYCOPY_NEEDED && YYCOPY_NEEDED +/* Copy COUNT objects from SRC to DST. The source and destination do + not overlap. */ +# ifndef YYCOPY +# if defined __GNUC__ && 1 < __GNUC__ +# define YYCOPY(Dst, Src, Count) \ + __builtin_memcpy (Dst, Src, (Count) * sizeof (*(Src))) +# else +# define YYCOPY(Dst, Src, Count) \ + do \ + { \ + YYSIZE_T yyi; \ + for (yyi = 0; yyi < (Count); yyi++) \ + (Dst)[yyi] = (Src)[yyi]; \ + } \ + while (0) +# endif +# endif +#endif /* !YYCOPY_NEEDED */ + +/* YYFINAL -- State number of the termination state. */ +#define YYFINAL 9 +/* YYLAST -- Last index in YYTABLE. */ +#define YYLAST 68 + +/* YYNTOKENS -- Number of terminals. */ +#define YYNTOKENS 32 +/* YYNNTS -- Number of nonterminals. */ +#define YYNNTS 10 +/* YYNRULES -- Number of rules. */ +#define YYNRULES 36 +/* YYNSTATES -- Number of states. */ +#define YYNSTATES 67 + +/* YYTRANSLATE[YYX] -- Symbol number corresponding to YYX as returned + by yylex, with out-of-bounds checking. */ +#define YYUNDEFTOK 2 +#define YYMAXUTOK 286 + +#define YYTRANSLATE(YYX) \ + ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK) + +/* YYTRANSLATE[TOKEN-NUM] -- Symbol number corresponding to TOKEN-NUM + as returned by yylex, without out-of-bounds checking. */ +static const yytype_uint8 yytranslate[] = +{ + 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 1, 2, 3, 4, + 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, + 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, + 25, 26, 27, 28, 29, 30, 31 +}; + +#if YYDEBUG + /* YYRLINE[YYN] -- Source line where rule number YYN was defined. */ +static const yytype_uint16 yyrline[] = +{ + 0, 221, 221, 233, 245, 260, 261, 265, 272, 278, + 287, 296, 303, 309, 315, 321, 327, 333, 339, 345, + 351, 357, 363, 369, 375, 381, 387, 393, 399, 405, + 411, 420, 429, 438, 444, 450, 456 +}; +#endif + +#if YYDEBUG || YYERROR_VERBOSE || 1 +/* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM. + First, the terminals, then, starting at YYNTOKENS, nonterminals. */ +static const char *const yytname[] = +{ + "$end", "error", "$undefined", "TK_SELECT", "TK_FROM", "TK_STAR", + "TK_COMMA", "TK_DOT", "TK_IS", "TK_LP", "TK_RP", "TK_NULL", "TK_FALSE", + "TK_TRUE", "TK_INTEGER", "TK_WHERE", "TK_SPACE", "TK_MINUS", + "TK_ILLEGAL", "TK_BY", "TK_STRING", "TK_ID", "TK_OR", "TK_AND", "TK_NOT", + "TK_EQ", "TK_NE", "TK_LT", "TK_GT", "TK_LE", "TK_GE", "TK_LIKE", + "$accept", "select", "proplist", "prop", "id", "number", "expr", + "string_val", "prop_val", "const_val", YY_NULLPTR +}; +#endif + +# ifdef YYPRINT +/* YYTOKNUM[NUM] -- (External) token number corresponding to the + (internal) symbol number NUM (which must be that of a token). */ +static const yytype_uint16 yytoknum[] = +{ + 0, 256, 257, 258, 259, 260, 261, 262, 263, 264, + 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, + 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, + 285, 286 +}; +# endif + +#define YYPACT_NINF -18 + +#define yypact_value_is_default(Yystate) \ + (!!((Yystate) == (-18))) + +#define YYTABLE_NINF -1 + +#define yytable_value_is_error(Yytable_value) \ + 0 + + /* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing + STATE-NUM. */ +static const yytype_int8 yypact[] = +{ + 7, 3, 12, -5, -18, -18, 24, 29, 35, -18, + -18, -5, 4, -5, 21, -18, -18, 17, 17, -18, + -18, -18, -18, 17, -18, -18, 11, -8, 25, 22, + -18, 17, 17, 16, -9, -9, -9, -9, -9, -9, + 23, -5, -5, -5, -5, -5, -5, -18, 45, -18, + -18, 37, -18, -18, -18, -18, -18, -18, -18, -18, + -18, -18, -18, -18, -18, -18, -18 +}; + + /* YYDEFACT[STATE-NUM] -- Default reduction number in state STATE-NUM. + Performed when YYTABLE does not specify something else to do. Zero + means the default is an error. */ +static const yytype_uint8 yydefact[] = +{ + 0, 0, 0, 0, 7, 10, 0, 5, 9, 1, + 2, 0, 0, 0, 3, 6, 8, 0, 0, 36, + 35, 11, 34, 0, 32, 33, 4, 0, 0, 0, + 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 12, 14, 13, + 29, 0, 16, 21, 18, 17, 19, 20, 31, 28, + 22, 27, 24, 23, 25, 26, 30 +}; + + /* YYPGOTO[NTERM-NUM]. */ +static const yytype_int8 yypgoto[] = +{ + -18, -18, 34, 1, 36, -18, -17, -18, 15, 28 +}; + + /* YYDEFGOTO[NTERM-NUM]. */ +static const yytype_int8 yydefgoto[] = +{ + -1, 2, 6, 24, 8, 25, 26, 59, 27, 28 +}; + + /* YYTABLE[YYPACT[STATE-NUM]] -- What to do in state STATE-NUM. If + positive, shift that token. If negative, reduce the rule whose + number is the opposite. If YYTABLE_NINF, syntax error. */ +static const yytype_uint8 yytable[] = +{ + 33, 29, 7, 19, 20, 21, 30, 3, 4, 4, + 1, 22, 9, 7, 48, 49, 5, 34, 35, 36, + 37, 38, 39, 40, 5, 5, 18, 50, 11, 19, + 20, 21, 47, 31, 32, 12, 17, 22, 5, 10, + 51, 23, 13, 58, 31, 32, 15, 14, 66, 16, + 41, 42, 43, 44, 45, 46, 60, 61, 62, 63, + 64, 65, 52, 53, 54, 55, 56, 57, 32 +}; + +static const yytype_uint8 yycheck[] = +{ + 8, 18, 1, 12, 13, 14, 23, 4, 5, 5, + 3, 20, 0, 12, 31, 32, 21, 25, 26, 27, + 28, 29, 30, 31, 21, 21, 9, 11, 4, 12, + 13, 14, 10, 22, 23, 6, 15, 20, 21, 3, + 24, 24, 7, 20, 22, 23, 12, 11, 11, 13, + 25, 26, 27, 28, 29, 30, 41, 42, 43, 44, + 45, 46, 34, 35, 36, 37, 38, 39, 23 +}; + + /* YYSTOS[STATE-NUM] -- The (internal number of the) accessing + symbol of state STATE-NUM. */ +static const yytype_uint8 yystos[] = +{ + 0, 3, 33, 4, 5, 21, 34, 35, 36, 0, + 36, 4, 6, 7, 36, 34, 36, 15, 9, 12, + 13, 14, 20, 24, 35, 37, 38, 40, 41, 38, + 38, 22, 23, 8, 25, 26, 27, 28, 29, 30, + 31, 25, 26, 27, 28, 29, 30, 10, 38, 38, + 11, 24, 41, 41, 41, 41, 41, 41, 20, 39, + 40, 40, 40, 40, 40, 40, 11 +}; + + /* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ +static const yytype_uint8 yyr1[] = +{ + 0, 32, 33, 33, 33, 34, 34, 34, 35, 35, + 36, 37, 38, 38, 38, 38, 38, 38, 38, 38, + 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, + 38, 39, 40, 41, 41, 41, 41 +}; + + /* YYR2[YYN] -- Number of symbols on the right hand side of rule YYN. */ +static const yytype_uint8 yyr2[] = +{ + 0, 2, 3, 4, 6, 1, 3, 1, 3, 1, + 1, 1, 3, 3, 3, 2, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 4, 1, 1, 1, 1, 1, 1 +}; + + +#define yyerrok (yyerrstatus = 0) +#define yyclearin (yychar = YYEMPTY) +#define YYEMPTY (-2) +#define YYEOF 0 + +#define YYACCEPT goto yyacceptlab +#define YYABORT goto yyabortlab +#define YYERROR goto yyerrorlab + + +#define YYRECOVERING() (!!yyerrstatus) + +#define YYBACKUP(Token, Value) \ +do \ + if (yychar == YYEMPTY) \ + { \ + yychar = (Token); \ + yylval = (Value); \ + YYPOPSTACK (yylen); \ + yystate = *yyssp; \ + goto yybackup; \ + } \ + else \ + { \ + yyerror (ctx, YY_("syntax error: cannot back up")); \ + YYERROR; \ + } \ +while (0) + +/* Error token number */ +#define YYTERROR 1 +#define YYERRCODE 256 + + + +/* Enable debugging if requested. */ +#if YYDEBUG + +# ifndef YYFPRINTF +# include /* INFRINGES ON USER NAME SPACE */ +# define YYFPRINTF fprintf +# endif + +# define YYDPRINTF(Args) \ +do { \ + if (yydebug) \ + YYFPRINTF Args; \ +} while (0) + +/* This macro is provided for backward compatibility. */ +#ifndef YY_LOCATION_PRINT +# define YY_LOCATION_PRINT(File, Loc) ((void) 0) +#endif + + +# define YY_SYMBOL_PRINT(Title, Type, Value, Location) \ +do { \ + if (yydebug) \ + { \ + YYFPRINTF (stderr, "%s ", Title); \ + yy_symbol_print (stderr, \ + Type, Value, ctx); \ + YYFPRINTF (stderr, "\n"); \ + } \ +} while (0) + + +/*----------------------------------------. +| Print this symbol's value on YYOUTPUT. | +`----------------------------------------*/ + +static void +yy_symbol_value_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep, struct parser *ctx) +{ + FILE *yyo = yyoutput; + YYUSE (yyo); + YYUSE (ctx); + if (!yyvaluep) + return; +# ifdef YYPRINT + if (yytype < YYNTOKENS) + YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep); +# endif + YYUSE (yytype); +} + + +/*--------------------------------. +| Print this symbol on YYOUTPUT. | +`--------------------------------*/ + +static void +yy_symbol_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep, struct parser *ctx) +{ + YYFPRINTF (yyoutput, "%s %s (", + yytype < YYNTOKENS ? "token" : "nterm", yytname[yytype]); + + yy_symbol_value_print (yyoutput, yytype, yyvaluep, ctx); + YYFPRINTF (yyoutput, ")"); +} + +/*------------------------------------------------------------------. +| yy_stack_print -- Print the state stack from its BOTTOM up to its | +| TOP (included). | +`------------------------------------------------------------------*/ + +static void +yy_stack_print (yytype_int16 *yybottom, yytype_int16 *yytop) +{ + YYFPRINTF (stderr, "Stack now"); + for (; yybottom <= yytop; yybottom++) + { + int yybot = *yybottom; + YYFPRINTF (stderr, " %d", yybot); + } + YYFPRINTF (stderr, "\n"); +} + +# define YY_STACK_PRINT(Bottom, Top) \ +do { \ + if (yydebug) \ + yy_stack_print ((Bottom), (Top)); \ +} while (0) + + +/*------------------------------------------------. +| Report that the YYRULE is going to be reduced. | +`------------------------------------------------*/ + +static void +yy_reduce_print (yytype_int16 *yyssp, YYSTYPE *yyvsp, int yyrule, struct parser *ctx) +{ + unsigned long int yylno = yyrline[yyrule]; + int yynrhs = yyr2[yyrule]; + int yyi; + YYFPRINTF (stderr, "Reducing stack by rule %d (line %lu):\n", + yyrule - 1, yylno); + /* The symbols being reduced. */ + for (yyi = 0; yyi < yynrhs; yyi++) + { + YYFPRINTF (stderr, " $%d = ", yyi + 1); + yy_symbol_print (stderr, + yystos[yyssp[yyi + 1 - yynrhs]], + &(yyvsp[(yyi + 1) - (yynrhs)]) + , ctx); + YYFPRINTF (stderr, "\n"); + } +} + +# define YY_REDUCE_PRINT(Rule) \ +do { \ + if (yydebug) \ + yy_reduce_print (yyssp, yyvsp, Rule, ctx); \ +} while (0) + +/* Nonzero means print parse trace. It is left uninitialized so that + multiple parsers can coexist. */ +int yydebug; +#else /* !YYDEBUG */ +# define YYDPRINTF(Args) +# define YY_SYMBOL_PRINT(Title, Type, Value, Location) +# define YY_STACK_PRINT(Bottom, Top) +# define YY_REDUCE_PRINT(Rule) +#endif /* !YYDEBUG */ + + +/* YYINITDEPTH -- initial size of the parser's stacks. */ +#ifndef YYINITDEPTH +# define YYINITDEPTH 200 +#endif + +/* YYMAXDEPTH -- maximum size the stacks can grow to (effective only + if the built-in stack extension method is used). + + Do not make this value too large; the results are undefined if + YYSTACK_ALLOC_MAXIMUM < YYSTACK_BYTES (YYMAXDEPTH) + evaluated with infinite-precision integer arithmetic. */ + +#ifndef YYMAXDEPTH +# define YYMAXDEPTH 10000 +#endif + + +#if YYERROR_VERBOSE + +# ifndef yystrlen +# if defined __GLIBC__ && defined _STRING_H +# define yystrlen strlen +# else +/* Return the length of YYSTR. */ +static YYSIZE_T +yystrlen (const char *yystr) +{ + YYSIZE_T yylen; + for (yylen = 0; yystr[yylen]; yylen++) + continue; + return yylen; +} +# endif +# endif + +# ifndef yystpcpy +# if defined __GLIBC__ && defined _STRING_H && defined _GNU_SOURCE +# define yystpcpy stpcpy +# else +/* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in + YYDEST. */ +static char * +yystpcpy (char *yydest, const char *yysrc) +{ + char *yyd = yydest; + const char *yys = yysrc; + + while ((*yyd++ = *yys++) != '\0') + continue; + + return yyd - 1; +} +# endif +# endif + +# ifndef yytnamerr +/* Copy to YYRES the contents of YYSTR after stripping away unnecessary + quotes and backslashes, so that it's suitable for yyerror. The + heuristic is that double-quoting is unnecessary unless the string + contains an apostrophe, a comma, or backslash (other than + backslash-backslash). YYSTR is taken from yytname. If YYRES is + null, do not copy; instead, return the length of what the result + would have been. */ +static YYSIZE_T +yytnamerr (char *yyres, const char *yystr) +{ + if (*yystr == '"') + { + YYSIZE_T yyn = 0; + char const *yyp = yystr; + + for (;;) + switch (*++yyp) + { + case '\'': + case ',': + goto do_not_strip_quotes; + + case '\\': + if (*++yyp != '\\') + goto do_not_strip_quotes; + /* Fall through. */ + default: + if (yyres) + yyres[yyn] = *yyp; + yyn++; + break; + + case '"': + if (yyres) + yyres[yyn] = '\0'; + return yyn; + } + do_not_strip_quotes: ; + } + + if (! yyres) + return yystrlen (yystr); + + return yystpcpy (yyres, yystr) - yyres; +} +# endif + +/* Copy into *YYMSG, which is of size *YYMSG_ALLOC, an error message + about the unexpected token YYTOKEN for the state stack whose top is + YYSSP. + + Return 0 if *YYMSG was successfully written. Return 1 if *YYMSG is + not large enough to hold the message. In that case, also set + *YYMSG_ALLOC to the required number of bytes. Return 2 if the + required number of bytes is too large to store. */ +static int +yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg, + yytype_int16 *yyssp, int yytoken) +{ + YYSIZE_T yysize0 = yytnamerr (YY_NULLPTR, yytname[yytoken]); + YYSIZE_T yysize = yysize0; + enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 }; + /* Internationalized format string. */ + const char *yyformat = YY_NULLPTR; + /* Arguments of yyformat. */ + char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM]; + /* Number of reported tokens (one for the "unexpected", one per + "expected"). */ + int yycount = 0; + + /* There are many possibilities here to consider: + - If this state is a consistent state with a default action, then + the only way this function was invoked is if the default action + is an error action. In that case, don't check for expected + tokens because there are none. + - The only way there can be no lookahead present (in yychar) is if + this state is a consistent state with a default action. Thus, + detecting the absence of a lookahead is sufficient to determine + that there is no unexpected or expected token to report. In that + case, just report a simple "syntax error". + - Don't assume there isn't a lookahead just because this state is a + consistent state with a default action. There might have been a + previous inconsistent state, consistent state with a non-default + action, or user semantic action that manipulated yychar. + - Of course, the expected token list depends on states to have + correct lookahead information, and it depends on the parser not + to perform extra reductions after fetching a lookahead from the + scanner and before detecting a syntax error. Thus, state merging + (from LALR or IELR) and default reductions corrupt the expected + token list. However, the list is correct for canonical LR with + one exception: it will still contain any token that will not be + accepted due to an error action in a later state. + */ + if (yytoken != YYEMPTY) + { + int yyn = yypact[*yyssp]; + yyarg[yycount++] = yytname[yytoken]; + if (!yypact_value_is_default (yyn)) + { + /* Start YYX at -YYN if negative to avoid negative indexes in + YYCHECK. In other words, skip the first -YYN actions for + this state because they are default actions. */ + int yyxbegin = yyn < 0 ? -yyn : 0; + /* Stay within bounds of both yycheck and yytname. */ + int yychecklim = YYLAST - yyn + 1; + int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS; + int yyx; + + for (yyx = yyxbegin; yyx < yyxend; ++yyx) + if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR + && !yytable_value_is_error (yytable[yyx + yyn])) + { + if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM) + { + yycount = 1; + yysize = yysize0; + break; + } + yyarg[yycount++] = yytname[yyx]; + { + YYSIZE_T yysize1 = yysize + yytnamerr (YY_NULLPTR, yytname[yyx]); + if (! (yysize <= yysize1 + && yysize1 <= YYSTACK_ALLOC_MAXIMUM)) + return 2; + yysize = yysize1; + } + } + } + } + + switch (yycount) + { +# define YYCASE_(N, S) \ + case N: \ + yyformat = S; \ + break + YYCASE_(0, YY_("syntax error")); + YYCASE_(1, YY_("syntax error, unexpected %s")); + YYCASE_(2, YY_("syntax error, unexpected %s, expecting %s")); + YYCASE_(3, YY_("syntax error, unexpected %s, expecting %s or %s")); + YYCASE_(4, YY_("syntax error, unexpected %s, expecting %s or %s or %s")); + YYCASE_(5, YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s")); +# undef YYCASE_ + } + + { + YYSIZE_T yysize1 = yysize + yystrlen (yyformat); + if (! (yysize <= yysize1 && yysize1 <= YYSTACK_ALLOC_MAXIMUM)) + return 2; + yysize = yysize1; + } + + if (*yymsg_alloc < yysize) + { + *yymsg_alloc = 2 * yysize; + if (! (yysize <= *yymsg_alloc + && *yymsg_alloc <= YYSTACK_ALLOC_MAXIMUM)) + *yymsg_alloc = YYSTACK_ALLOC_MAXIMUM; + return 1; + } + + /* Avoid sprintf, as that infringes on the user's name space. + Don't have undefined behavior even if the translation + produced a string with the wrong number of "%s"s. */ + { + char *yyp = *yymsg; + int yyi = 0; + while ((*yyp = *yyformat) != '\0') + if (*yyp == '%' && yyformat[1] == 's' && yyi < yycount) + { + yyp += yytnamerr (yyp, yyarg[yyi++]); + yyformat += 2; + } + else + { + yyp++; + yyformat++; + } + } + return 0; +} +#endif /* YYERROR_VERBOSE */ + +/*-----------------------------------------------. +| Release the memory associated to this symbol. | +`-----------------------------------------------*/ + +static void +yydestruct (const char *yymsg, int yytype, YYSTYPE *yyvaluep, struct parser *ctx) +{ + YYUSE (yyvaluep); + YYUSE (ctx); + if (!yymsg) + yymsg = "Deleting"; + YY_SYMBOL_PRINT (yymsg, yytype, yyvaluep, yylocationp); + + YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN + YYUSE (yytype); + YY_IGNORE_MAYBE_UNINITIALIZED_END +} + + + + +/*----------. +| yyparse. | +`----------*/ + +int +yyparse (struct parser *ctx) +{ +/* The lookahead symbol. */ +int yychar; + + +/* The semantic value of the lookahead symbol. */ +/* Default value used for initialization, for pacifying older GCCs + or non-GCC compilers. */ +YY_INITIAL_VALUE (static YYSTYPE yyval_default;) +YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); + + /* Number of syntax errors so far. */ + int yynerrs; + + int yystate; + /* Number of tokens to shift before error messages enabled. */ + int yyerrstatus; + + /* The stacks and their tools: + 'yyss': related to states. + 'yyvs': related to semantic values. + + Refer to the stacks through separate pointers, to allow yyoverflow + to reallocate them elsewhere. */ + + /* The state stack. */ + yytype_int16 yyssa[YYINITDEPTH]; + yytype_int16 *yyss; + yytype_int16 *yyssp; + + /* The semantic value stack. */ + YYSTYPE yyvsa[YYINITDEPTH]; + YYSTYPE *yyvs; + YYSTYPE *yyvsp; + + YYSIZE_T yystacksize; + + int yyn; + int yyresult; + /* Lookahead token as an internal (translated) token number. */ + int yytoken = 0; + /* The variables used to return semantic value and location from the + action routines. */ + YYSTYPE yyval; + +#if YYERROR_VERBOSE + /* Buffer for error messages, and its allocated size. */ + char yymsgbuf[128]; + char *yymsg = yymsgbuf; + YYSIZE_T yymsg_alloc = sizeof yymsgbuf; +#endif + +#define YYPOPSTACK(N) (yyvsp -= (N), yyssp -= (N)) + + /* The number of symbols on the RHS of the reduced rule. + Keep to zero when no symbol should be popped. */ + int yylen = 0; + + yyssp = yyss = yyssa; + yyvsp = yyvs = yyvsa; + yystacksize = YYINITDEPTH; + + YYDPRINTF ((stderr, "Starting parse\n")); + + yystate = 0; + yyerrstatus = 0; + yynerrs = 0; + yychar = YYEMPTY; /* Cause a token to be read. */ + goto yysetstate; + +/*------------------------------------------------------------. +| yynewstate -- Push a new state, which is found in yystate. | +`------------------------------------------------------------*/ + yynewstate: + /* In all cases, when you get here, the value and location stacks + have just been pushed. So pushing a state here evens the stacks. */ + yyssp++; + + yysetstate: + *yyssp = yystate; + + if (yyss + yystacksize - 1 <= yyssp) + { + /* Get the current used size of the three stacks, in elements. */ + YYSIZE_T yysize = yyssp - yyss + 1; + +#ifdef yyoverflow + { + /* Give user a chance to reallocate the stack. Use copies of + these so that the &'s don't force the real ones into + memory. */ + YYSTYPE *yyvs1 = yyvs; + yytype_int16 *yyss1 = yyss; + + /* Each stack pointer address is followed by the size of the + data in use in that stack, in bytes. This used to be a + conditional around just the two extra args, but that might + be undefined if yyoverflow is a macro. */ + yyoverflow (YY_("memory exhausted"), + &yyss1, yysize * sizeof (*yyssp), + &yyvs1, yysize * sizeof (*yyvsp), + &yystacksize); + + yyss = yyss1; + yyvs = yyvs1; + } +#else /* no yyoverflow */ +# ifndef YYSTACK_RELOCATE + goto yyexhaustedlab; +# else + /* Extend the stack our own way. */ + if (YYMAXDEPTH <= yystacksize) + goto yyexhaustedlab; + yystacksize *= 2; + if (YYMAXDEPTH < yystacksize) + yystacksize = YYMAXDEPTH; + + { + yytype_int16 *yyss1 = yyss; + union yyalloc *yyptr = + (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize)); + if (! yyptr) + goto yyexhaustedlab; + YYSTACK_RELOCATE (yyss_alloc, yyss); + YYSTACK_RELOCATE (yyvs_alloc, yyvs); +# undef YYSTACK_RELOCATE + if (yyss1 != yyssa) + YYSTACK_FREE (yyss1); + } +# endif +#endif /* no yyoverflow */ + + yyssp = yyss + yysize - 1; + yyvsp = yyvs + yysize - 1; + + YYDPRINTF ((stderr, "Stack size increased to %lu\n", + (unsigned long int) yystacksize)); + + if (yyss + yystacksize - 1 <= yyssp) + YYABORT; + } + + YYDPRINTF ((stderr, "Entering state %d\n", yystate)); + + if (yystate == YYFINAL) + YYACCEPT; + + goto yybackup; + +/*-----------. +| yybackup. | +`-----------*/ +yybackup: + + /* Do appropriate processing given the current state. Read a + lookahead token if we need one and don't already have one. */ + + /* First try to decide what to do without reference to lookahead token. */ + yyn = yypact[yystate]; + if (yypact_value_is_default (yyn)) + goto yydefault; + + /* Not known => get a lookahead token if don't already have one. */ + + /* YYCHAR is either YYEMPTY or YYEOF or a valid lookahead symbol. */ + if (yychar == YYEMPTY) + { + YYDPRINTF ((stderr, "Reading a token: ")); + yychar = yylex (&yylval, ctx); + } + + if (yychar <= YYEOF) + { + yychar = yytoken = YYEOF; + YYDPRINTF ((stderr, "Now at end of input.\n")); + } + else + { + yytoken = YYTRANSLATE (yychar); + YY_SYMBOL_PRINT ("Next token is", yytoken, &yylval, &yylloc); + } + + /* If the proper action on seeing token YYTOKEN is to reduce or to + detect an error, take that action. */ + yyn += yytoken; + if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken) + goto yydefault; + yyn = yytable[yyn]; + if (yyn <= 0) + { + if (yytable_value_is_error (yyn)) + goto yyerrlab; + yyn = -yyn; + goto yyreduce; + } + + /* Count tokens shifted since error; after three, turn off error + status. */ + if (yyerrstatus) + yyerrstatus--; + + /* Shift the lookahead token. */ + YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc); + + /* Discard the shifted token. */ + yychar = YYEMPTY; + + yystate = yyn; + YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN + *++yyvsp = yylval; + YY_IGNORE_MAYBE_UNINITIALIZED_END + + goto yynewstate; + + +/*-----------------------------------------------------------. +| yydefault -- do the default action for the current state. | +`-----------------------------------------------------------*/ +yydefault: + yyn = yydefact[yystate]; + if (yyn == 0) + goto yyerrlab; + goto yyreduce; + + +/*-----------------------------. +| yyreduce -- Do a reduction. | +`-----------------------------*/ +yyreduce: + /* yyn is the number of a rule to reduce with. */ + yylen = yyr2[yyn]; + + /* If YYLEN is nonzero, implement the default value of the action: + '$$ = $1'. + + Otherwise, the following line sets YYVAL to garbage. + This behavior is undocumented and Bison + users should not rely upon it. Assigning to YYVAL + unconditionally makes the parser a bit smaller, and it avoids a + GCC warning that YYVAL may be used uninitialized. */ + yyval = yyvsp[1-yylen]; + + + YY_REDUCE_PRINT (yyn); + switch (yyn) + { + case 2: +#line 222 "wql.y" /* yacc.c:1646 */ + { + HRESULT hr; + struct parser *parser = ctx; + struct view *view; + + hr = create_view( NULL, (yyvsp[0].string), NULL, &view ); + if (hr != S_OK) + YYABORT; + + PARSER_BUBBLE_UP_VIEW( parser, (yyval.view), view ); + } +#line 1482 "wql.tab.c" /* yacc.c:1646 */ + break; + + case 3: +#line 234 "wql.y" /* yacc.c:1646 */ + { + HRESULT hr; + struct parser *parser = ctx; + struct view *view; + + hr = create_view( (yyvsp[-2].proplist), (yyvsp[0].string), NULL, &view ); + if (hr != S_OK) + YYABORT; + + PARSER_BUBBLE_UP_VIEW( parser, (yyval.view), view ); + } +#line 1498 "wql.tab.c" /* yacc.c:1646 */ + break; + + case 4: +#line 246 "wql.y" /* yacc.c:1646 */ + { + HRESULT hr; + struct parser *parser = ctx; + struct view *view; + + hr = create_view( (yyvsp[-4].proplist), (yyvsp[-2].string), (yyvsp[0].expr), &view ); + if (hr != S_OK) + YYABORT; + + PARSER_BUBBLE_UP_VIEW( parser, (yyval.view), view ); + } +#line 1514 "wql.tab.c" /* yacc.c:1646 */ + break; + + case 6: +#line 262 "wql.y" /* yacc.c:1646 */ + { + (yyvsp[-2].proplist)->next = (yyvsp[0].proplist); + } +#line 1522 "wql.tab.c" /* yacc.c:1646 */ + break; + + case 7: +#line 266 "wql.y" /* yacc.c:1646 */ + { + (yyval.proplist) = NULL; + } +#line 1530 "wql.tab.c" /* yacc.c:1646 */ + break; + + case 8: +#line 273 "wql.y" /* yacc.c:1646 */ + { + (yyval.proplist) = alloc_property( ctx, (yyvsp[-2].string), (yyvsp[0].string) ); + if (!(yyval.proplist)) + YYABORT; + } +#line 1540 "wql.tab.c" /* yacc.c:1646 */ + break; + + case 9: +#line 279 "wql.y" /* yacc.c:1646 */ + { + (yyval.proplist) = alloc_property( ctx, NULL, (yyvsp[0].string) ); + if (!(yyval.proplist)) + YYABORT; + } +#line 1550 "wql.tab.c" /* yacc.c:1646 */ + break; + + case 10: +#line 288 "wql.y" /* yacc.c:1646 */ + { + (yyval.string) = get_string( ctx, &(yyvsp[0].str) ); + if (!(yyval.string)) + YYABORT; + } +#line 1560 "wql.tab.c" /* yacc.c:1646 */ + break; + + case 11: +#line 297 "wql.y" /* yacc.c:1646 */ + { + (yyval.integer) = get_int( ctx ); + } +#line 1568 "wql.tab.c" /* yacc.c:1646 */ + break; + + case 12: +#line 304 "wql.y" /* yacc.c:1646 */ + { + (yyval.expr) = (yyvsp[-1].expr); + if (!(yyval.expr)) + YYABORT; + } +#line 1578 "wql.tab.c" /* yacc.c:1646 */ + break; + + case 13: +#line 310 "wql.y" /* yacc.c:1646 */ + { + (yyval.expr) = expr_complex( ctx, (yyvsp[-2].expr), OP_AND, (yyvsp[0].expr) ); + if (!(yyval.expr)) + YYABORT; + } +#line 1588 "wql.tab.c" /* yacc.c:1646 */ + break; + + case 14: +#line 316 "wql.y" /* yacc.c:1646 */ + { + (yyval.expr) = expr_complex( ctx, (yyvsp[-2].expr), OP_OR, (yyvsp[0].expr) ); + if (!(yyval.expr)) + YYABORT; + } +#line 1598 "wql.tab.c" /* yacc.c:1646 */ + break; + + case 15: +#line 322 "wql.y" /* yacc.c:1646 */ + { + (yyval.expr) = expr_unary( ctx, (yyvsp[0].expr), OP_NOT ); + if (!(yyval.expr)) + YYABORT; + } +#line 1608 "wql.tab.c" /* yacc.c:1646 */ + break; + + case 16: +#line 328 "wql.y" /* yacc.c:1646 */ + { + (yyval.expr) = expr_complex( ctx, (yyvsp[-2].expr), OP_EQ, (yyvsp[0].expr) ); + if (!(yyval.expr)) + YYABORT; + } +#line 1618 "wql.tab.c" /* yacc.c:1646 */ + break; + + case 17: +#line 334 "wql.y" /* yacc.c:1646 */ + { + (yyval.expr) = expr_complex( ctx, (yyvsp[-2].expr), OP_GT, (yyvsp[0].expr) ); + if (!(yyval.expr)) + YYABORT; + } +#line 1628 "wql.tab.c" /* yacc.c:1646 */ + break; + + case 18: +#line 340 "wql.y" /* yacc.c:1646 */ + { + (yyval.expr) = expr_complex( ctx, (yyvsp[-2].expr), OP_LT, (yyvsp[0].expr) ); + if (!(yyval.expr)) + YYABORT; + } +#line 1638 "wql.tab.c" /* yacc.c:1646 */ + break; + + case 19: +#line 346 "wql.y" /* yacc.c:1646 */ + { + (yyval.expr) = expr_complex( ctx, (yyvsp[-2].expr), OP_LE, (yyvsp[0].expr) ); + if (!(yyval.expr)) + YYABORT; + } +#line 1648 "wql.tab.c" /* yacc.c:1646 */ + break; + + case 20: +#line 352 "wql.y" /* yacc.c:1646 */ + { + (yyval.expr) = expr_complex( ctx, (yyvsp[-2].expr), OP_GE, (yyvsp[0].expr) ); + if (!(yyval.expr)) + YYABORT; + } +#line 1658 "wql.tab.c" /* yacc.c:1646 */ + break; + + case 21: +#line 358 "wql.y" /* yacc.c:1646 */ + { + (yyval.expr) = expr_complex( ctx, (yyvsp[-2].expr), OP_NE, (yyvsp[0].expr) ); + if (!(yyval.expr)) + YYABORT; + } +#line 1668 "wql.tab.c" /* yacc.c:1646 */ + break; + + case 22: +#line 364 "wql.y" /* yacc.c:1646 */ + { + (yyval.expr) = expr_complex( ctx, (yyvsp[-2].expr), OP_EQ, (yyvsp[0].expr) ); + if (!(yyval.expr)) + YYABORT; + } +#line 1678 "wql.tab.c" /* yacc.c:1646 */ + break; + + case 23: +#line 370 "wql.y" /* yacc.c:1646 */ + { + (yyval.expr) = expr_complex( ctx, (yyvsp[-2].expr), OP_GT, (yyvsp[0].expr) ); + if (!(yyval.expr)) + YYABORT; + } +#line 1688 "wql.tab.c" /* yacc.c:1646 */ + break; + + case 24: +#line 376 "wql.y" /* yacc.c:1646 */ + { + (yyval.expr) = expr_complex( ctx, (yyvsp[-2].expr), OP_LT, (yyvsp[0].expr) ); + if (!(yyval.expr)) + YYABORT; + } +#line 1698 "wql.tab.c" /* yacc.c:1646 */ + break; + + case 25: +#line 382 "wql.y" /* yacc.c:1646 */ + { + (yyval.expr) = expr_complex( ctx, (yyvsp[-2].expr), OP_LE, (yyvsp[0].expr) ); + if (!(yyval.expr)) + YYABORT; + } +#line 1708 "wql.tab.c" /* yacc.c:1646 */ + break; + + case 26: +#line 388 "wql.y" /* yacc.c:1646 */ + { + (yyval.expr) = expr_complex( ctx, (yyvsp[-2].expr), OP_GE, (yyvsp[0].expr) ); + if (!(yyval.expr)) + YYABORT; + } +#line 1718 "wql.tab.c" /* yacc.c:1646 */ + break; + + case 27: +#line 394 "wql.y" /* yacc.c:1646 */ + { + (yyval.expr) = expr_complex( ctx, (yyvsp[-2].expr), OP_NE, (yyvsp[0].expr) ); + if (!(yyval.expr)) + YYABORT; + } +#line 1728 "wql.tab.c" /* yacc.c:1646 */ + break; + + case 28: +#line 400 "wql.y" /* yacc.c:1646 */ + { + (yyval.expr) = expr_complex( ctx, (yyvsp[-2].expr), OP_LIKE, (yyvsp[0].expr) ); + if (!(yyval.expr)) + YYABORT; + } +#line 1738 "wql.tab.c" /* yacc.c:1646 */ + break; + + case 29: +#line 406 "wql.y" /* yacc.c:1646 */ + { + (yyval.expr) = expr_unary( ctx, (yyvsp[-2].expr), OP_ISNULL ); + if (!(yyval.expr)) + YYABORT; + } +#line 1748 "wql.tab.c" /* yacc.c:1646 */ + break; + + case 30: +#line 412 "wql.y" /* yacc.c:1646 */ + { + (yyval.expr) = expr_unary( ctx, (yyvsp[-3].expr), OP_NOTNULL ); + if (!(yyval.expr)) + YYABORT; + } +#line 1758 "wql.tab.c" /* yacc.c:1646 */ + break; + + case 31: +#line 421 "wql.y" /* yacc.c:1646 */ + { + (yyval.expr) = expr_sval( ctx, &(yyvsp[0].str) ); + if (!(yyval.expr)) + YYABORT; + } +#line 1768 "wql.tab.c" /* yacc.c:1646 */ + break; + + case 32: +#line 430 "wql.y" /* yacc.c:1646 */ + { + (yyval.expr) = expr_propval( ctx, (yyvsp[0].proplist) ); + if (!(yyval.expr)) + YYABORT; + } +#line 1778 "wql.tab.c" /* yacc.c:1646 */ + break; + + case 33: +#line 439 "wql.y" /* yacc.c:1646 */ + { + (yyval.expr) = expr_ival( ctx, (yyvsp[0].integer) ); + if (!(yyval.expr)) + YYABORT; + } +#line 1788 "wql.tab.c" /* yacc.c:1646 */ + break; + + case 34: +#line 445 "wql.y" /* yacc.c:1646 */ + { + (yyval.expr) = expr_sval( ctx, &(yyvsp[0].str) ); + if (!(yyval.expr)) + YYABORT; + } +#line 1798 "wql.tab.c" /* yacc.c:1646 */ + break; + + case 35: +#line 451 "wql.y" /* yacc.c:1646 */ + { + (yyval.expr) = expr_bval( ctx, -1 ); + if (!(yyval.expr)) + YYABORT; + } +#line 1808 "wql.tab.c" /* yacc.c:1646 */ + break; + + case 36: +#line 457 "wql.y" /* yacc.c:1646 */ + { + (yyval.expr) = expr_bval( ctx, 0 ); + if (!(yyval.expr)) + YYABORT; + } +#line 1818 "wql.tab.c" /* yacc.c:1646 */ + break; + + +#line 1822 "wql.tab.c" /* yacc.c:1646 */ + default: break; + } + /* User semantic actions sometimes alter yychar, and that requires + that yytoken be updated with the new translation. We take the + approach of translating immediately before every use of yytoken. + One alternative is translating here after every semantic action, + but that translation would be missed if the semantic action invokes + YYABORT, YYACCEPT, or YYERROR immediately after altering yychar or + if it invokes YYBACKUP. In the case of YYABORT or YYACCEPT, an + incorrect destructor might then be invoked immediately. In the + case of YYERROR or YYBACKUP, subsequent parser actions might lead + to an incorrect destructor call or verbose syntax error message + before the lookahead is translated. */ + YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc); + + YYPOPSTACK (yylen); + yylen = 0; + YY_STACK_PRINT (yyss, yyssp); + + *++yyvsp = yyval; + + /* Now 'shift' the result of the reduction. Determine what state + that goes to, based on the state we popped back to and the rule + number reduced by. */ + + yyn = yyr1[yyn]; + + yystate = yypgoto[yyn - YYNTOKENS] + *yyssp; + if (0 <= yystate && yystate <= YYLAST && yycheck[yystate] == *yyssp) + yystate = yytable[yystate]; + else + yystate = yydefgoto[yyn - YYNTOKENS]; + + goto yynewstate; + + +/*--------------------------------------. +| yyerrlab -- here on detecting error. | +`--------------------------------------*/ +yyerrlab: + /* Make sure we have latest lookahead translation. See comments at + user semantic actions for why this is necessary. */ + yytoken = yychar == YYEMPTY ? YYEMPTY : YYTRANSLATE (yychar); + + /* If not already recovering from an error, report this error. */ + if (!yyerrstatus) + { + ++yynerrs; +#if ! YYERROR_VERBOSE + yyerror (ctx, YY_("syntax error")); +#else +# define YYSYNTAX_ERROR yysyntax_error (&yymsg_alloc, &yymsg, \ + yyssp, yytoken) + { + char const *yymsgp = YY_("syntax error"); + int yysyntax_error_status; + yysyntax_error_status = YYSYNTAX_ERROR; + if (yysyntax_error_status == 0) + yymsgp = yymsg; + else if (yysyntax_error_status == 1) + { + if (yymsg != yymsgbuf) + YYSTACK_FREE (yymsg); + yymsg = (char *) YYSTACK_ALLOC (yymsg_alloc); + if (!yymsg) + { + yymsg = yymsgbuf; + yymsg_alloc = sizeof yymsgbuf; + yysyntax_error_status = 2; + } + else + { + yysyntax_error_status = YYSYNTAX_ERROR; + yymsgp = yymsg; + } + } + yyerror (ctx, yymsgp); + if (yysyntax_error_status == 2) + goto yyexhaustedlab; + } +# undef YYSYNTAX_ERROR +#endif + } + + + + if (yyerrstatus == 3) + { + /* If just tried and failed to reuse lookahead token after an + error, discard it. */ + + if (yychar <= YYEOF) + { + /* Return failure if at end of input. */ + if (yychar == YYEOF) + YYABORT; + } + else + { + yydestruct ("Error: discarding", + yytoken, &yylval, ctx); + yychar = YYEMPTY; + } + } + + /* Else will try to reuse lookahead token after shifting the error + token. */ + goto yyerrlab1; + + +/*---------------------------------------------------. +| yyerrorlab -- error raised explicitly by YYERROR. | +`---------------------------------------------------*/ +yyerrorlab: + + /* Pacify compilers like GCC when the user code never invokes + YYERROR and the label yyerrorlab therefore never appears in user + code. */ + if (/*CONSTCOND*/ 0) + goto yyerrorlab; + + /* Do not reclaim the symbols of the rule whose action triggered + this YYERROR. */ + YYPOPSTACK (yylen); + yylen = 0; + YY_STACK_PRINT (yyss, yyssp); + yystate = *yyssp; + goto yyerrlab1; + + +/*-------------------------------------------------------------. +| yyerrlab1 -- common code for both syntax error and YYERROR. | +`-------------------------------------------------------------*/ +yyerrlab1: + yyerrstatus = 3; /* Each real token shifted decrements this. */ + + for (;;) + { + yyn = yypact[yystate]; + if (!yypact_value_is_default (yyn)) + { + yyn += YYTERROR; + if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR) + { + yyn = yytable[yyn]; + if (0 < yyn) + break; + } + } + + /* Pop the current state because it cannot handle the error token. */ + if (yyssp == yyss) + YYABORT; + + + yydestruct ("Error: popping", + yystos[yystate], yyvsp, ctx); + YYPOPSTACK (1); + yystate = *yyssp; + YY_STACK_PRINT (yyss, yyssp); + } + + YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN + *++yyvsp = yylval; + YY_IGNORE_MAYBE_UNINITIALIZED_END + + + /* Shift the error token. */ + YY_SYMBOL_PRINT ("Shifting", yystos[yyn], yyvsp, yylsp); + + yystate = yyn; + goto yynewstate; + + +/*-------------------------------------. +| yyacceptlab -- YYACCEPT comes here. | +`-------------------------------------*/ +yyacceptlab: + yyresult = 0; + goto yyreturn; + +/*-----------------------------------. +| yyabortlab -- YYABORT comes here. | +`-----------------------------------*/ +yyabortlab: + yyresult = 1; + goto yyreturn; + +#if !defined yyoverflow || YYERROR_VERBOSE +/*-------------------------------------------------. +| yyexhaustedlab -- memory exhaustion comes here. | +`-------------------------------------------------*/ +yyexhaustedlab: + yyerror (ctx, YY_("memory exhausted")); + yyresult = 2; + /* Fall through. */ +#endif + +yyreturn: + if (yychar != YYEMPTY) + { + /* Make sure we have latest lookahead translation. See comments at + user semantic actions for why this is necessary. */ + yytoken = YYTRANSLATE (yychar); + yydestruct ("Cleanup: discarding lookahead", + yytoken, &yylval, ctx); + } + /* Do not reclaim the symbols of the rule whose action triggered + this YYABORT or YYACCEPT. */ + YYPOPSTACK (yylen); + YY_STACK_PRINT (yyss, yyssp); + while (yyssp != yyss) + { + yydestruct ("Cleanup: popping", + yystos[*yyssp], yyvsp, ctx); + YYPOPSTACK (1); + } +#ifndef yyoverflow + if (yyss != yyssa) + YYSTACK_FREE (yyss); +#endif +#if YYERROR_VERBOSE + if (yymsg != yymsgbuf) + YYSTACK_FREE (yymsg); +#endif + return yyresult; +} +#line 464 "wql.y" /* yacc.c:1906 */ + + +HRESULT parse_query( const WCHAR *str, struct view **view, struct list *mem ) +{ + struct parser parser; + int ret; + + *view = NULL; + + parser.cmd = str; + parser.idx = 0; + parser.len = 0; + parser.error = WBEM_E_INVALID_QUERY; + parser.view = view; + parser.mem = mem; + + ret = wql_parse( &parser ); + TRACE("wql_parse returned %d\n", ret); + if (ret) + { + if (*parser.view) + { + destroy_view( *parser.view ); + *parser.view = NULL; + } + return parser.error; + } + return S_OK; +} + +static const char id_char[] = +{ + 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, + 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, + 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, +}; + +struct keyword +{ + const WCHAR *name; + unsigned int len; + int type; +}; + +#define MAX_TOKEN_LEN 6 + +static const WCHAR andW[] = {'A','N','D'}; +static const WCHAR byW[] = {'B','Y'}; +static const WCHAR falseW[] = {'F','A','L','S','E'}; +static const WCHAR fromW[] = {'F','R','O','M'}; +static const WCHAR isW[] = {'I','S'}; +static const WCHAR likeW[] = {'L','I','K','E'}; +static const WCHAR notW[] = {'N','O','T'}; +static const WCHAR nullW[] = {'N','U','L','L'}; +static const WCHAR orW[] = {'O','R'}; +static const WCHAR selectW[] = {'S','E','L','E','C','T'}; +static const WCHAR trueW[] = {'T','R','U','E'}; +static const WCHAR whereW[] = {'W','H','E','R','E'}; + +static const struct keyword keyword_table[] = +{ + { andW, SIZEOF(andW), TK_AND }, + { byW, SIZEOF(byW), TK_BY }, + { falseW, SIZEOF(falseW), TK_FALSE }, + { fromW, SIZEOF(fromW), TK_FROM }, + { isW, SIZEOF(isW), TK_IS }, + { likeW, SIZEOF(likeW), TK_LIKE }, + { notW, SIZEOF(notW), TK_NOT }, + { nullW, SIZEOF(nullW), TK_NULL }, + { orW, SIZEOF(orW), TK_OR }, + { selectW, SIZEOF(selectW), TK_SELECT }, + { trueW, SIZEOF(trueW), TK_TRUE }, + { whereW, SIZEOF(whereW), TK_WHERE } +}; + +static int cmp_keyword( const void *arg1, const void *arg2 ) +{ + const struct keyword *key1 = arg1, *key2 = arg2; + int len = min( key1->len, key2->len ); + int ret; + + if ((ret = memicmpW( key1->name, key2->name, len ))) return ret; + if (key1->len < key2->len) return -1; + else if (key1->len > key2->len) return 1; + return 0; +} + +static int keyword_type( const WCHAR *str, unsigned int len ) +{ + struct keyword key, *ret; + + if (len > MAX_TOKEN_LEN) return TK_ID; + + key.name = str; + key.len = len; + key.type = 0; + ret = bsearch( &key, keyword_table, SIZEOF(keyword_table), sizeof(struct keyword), cmp_keyword ); + if (ret) return ret->type; + return TK_ID; +} + +static int get_token( const WCHAR *s, int *token ) +{ + int i; + + switch (*s) + { + case ' ': + case '\t': + case '\r': + case '\n': + for (i = 1; isspaceW( s[i] ); i++) {} + *token = TK_SPACE; + return i; + case '-': + if (!s[1]) return -1; + *token = TK_MINUS; + return 1; + case '(': + *token = TK_LP; + return 1; + case ')': + *token = TK_RP; + return 1; + case '*': + *token = TK_STAR; + return 1; + case '=': + *token = TK_EQ; + return 1; + case '<': + if (s[1] == '=' ) + { + *token = TK_LE; + return 2; + } + else if (s[1] == '>') + { + *token = TK_NE; + return 2; + } + else + { + *token = TK_LT; + return 1; + } + case '>': + if (s[1] == '=') + { + *token = TK_GE; + return 2; + } + else + { + *token = TK_GT; + return 1; + } + case '!': + if (s[1] != '=') + { + *token = TK_ILLEGAL; + return 2; + } + else + { + *token = TK_NE; + return 2; + } + case ',': + *token = TK_COMMA; + return 1; + case '\"': + case '\'': + for (i = 1; s[i]; i++) + { + if (s[i] == s[0]) break; + } + if (s[i]) i++; + *token = TK_STRING; + return i; + case '.': + if (!isdigitW( s[1] )) + { + *token = TK_DOT; + return 1; + } + /* fall through */ + case '0': case '1': case '2': case '3': case '4': + case '5': case '6': case '7': case '8': case '9': + *token = TK_INTEGER; + for (i = 1; isdigitW( s[i] ); i++) {} + return i; + default: + if (!id_char[*s]) break; + + for (i = 1; id_char[s[i]]; i++) {} + *token = keyword_type( s, i ); + return i; + } + *token = TK_ILLEGAL; + return 1; +} + +static int wql_lex( void *p, struct parser *parser ) +{ + struct string *str = p; + int token = -1; + do + { + parser->idx += parser->len; + if (!parser->cmd[parser->idx]) return 0; + parser->len = get_token( &parser->cmd[parser->idx], &token ); + if (!parser->len) break; + + str->data = &parser->cmd[parser->idx]; + str->len = parser->len; + } while (token == TK_SPACE); + return token; +} + +static int wql_error( struct parser *parser, const char *str ) +{ + ERR("%s\n", str); + return 0; +} diff --git a/reactos/dll/win32/wbemprox/wql.y b/reactos/dll/win32/wbemprox/wql.y new file mode 100644 index 00000000000..98b03786776 --- /dev/null +++ b/reactos/dll/win32/wbemprox/wql.y @@ -0,0 +1,701 @@ +%{ + +/* + * Copyright 2012 Hans Leidekker for CodeWeavers + * + * 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 "config.h" +#include + +#include "windef.h" +#include "winbase.h" +#include "wbemcli.h" +#include "wbemprox_private.h" + +#include "wine/list.h" +#include "wine/debug.h" +#include "wine/unicode.h" + +WINE_DEFAULT_DEBUG_CHANNEL(wbemprox); + +struct parser +{ + const WCHAR *cmd; + UINT idx; + UINT len; + HRESULT error; + struct view **view; + struct list *mem; +}; + +struct string +{ + const WCHAR *data; + int len; +}; + +static void *alloc_mem( struct parser *parser, UINT size ) +{ + struct list *mem = heap_alloc( sizeof(struct list) + size ); + list_add_tail( parser->mem, mem ); + return &mem[1]; +} + +static struct property *alloc_property( struct parser *parser, const WCHAR *class, const WCHAR *name ) +{ + struct property *prop = alloc_mem( parser, sizeof(*prop) ); + if (prop) + { + prop->name = name; + prop->class = class; + prop->next = NULL; + } + return prop; +} + +static WCHAR *get_string( struct parser *parser, const struct string *str ) +{ + const WCHAR *p = str->data; + int len = str->len; + WCHAR *ret; + + if ((p[0] == '\"' && p[len - 1] != '\"') || + (p[0] == '\'' && p[len - 1] != '\'')) return NULL; + if ((p[0] == '\"' && p[len - 1] == '\"') || + (p[0] == '\'' && p[len - 1] == '\'')) + { + p++; + len -= 2; + } + if (!(ret = alloc_mem( parser, (len + 1) * sizeof(WCHAR) ))) return NULL; + memcpy( ret, p, len * sizeof(WCHAR) ); + ret[len] = 0; + return ret; +} + +static int get_int( struct parser *parser ) +{ + const WCHAR *p = &parser->cmd[parser->idx]; + int i, ret = 0; + + for (i = 0; i < parser->len; i++) + { + if (p[i] < '0' || p[i] > '9') + { + ERR("should only be numbers here!\n"); + break; + } + ret = (p[i] - '0') + ret * 10; + } + return ret; +} + +static struct expr *expr_complex( struct parser *parser, struct expr *l, UINT op, struct expr *r ) +{ + struct expr *e = alloc_mem( parser, sizeof(*e) ); + if (e) + { + e->type = EXPR_COMPLEX; + e->u.expr.left = l; + e->u.expr.op = op; + e->u.expr.right = r; + } + return e; +} + +static struct expr *expr_unary( struct parser *parser, struct expr *l, UINT op ) +{ + struct expr *e = alloc_mem( parser, sizeof(*e) ); + if (e) + { + e->type = EXPR_UNARY; + e->u.expr.left = l; + e->u.expr.op = op; + e->u.expr.right = NULL; + } + return e; +} + +static struct expr *expr_ival( struct parser *parser, int val ) +{ + struct expr *e = alloc_mem( parser, sizeof *e ); + if (e) + { + e->type = EXPR_IVAL; + e->u.ival = val; + } + return e; +} + +static struct expr *expr_sval( struct parser *parser, const struct string *str ) +{ + struct expr *e = alloc_mem( parser, sizeof *e ); + if (e) + { + e->type = EXPR_SVAL; + e->u.sval = get_string( parser, str ); + if (!e->u.sval) + return NULL; /* e will be freed by query destructor */ + } + return e; +} + +static struct expr *expr_bval( struct parser *parser, int val ) +{ + struct expr *e = alloc_mem( parser, sizeof *e ); + if (e) + { + e->type = EXPR_BVAL; + e->u.ival = val; + } + return e; +} + +static struct expr *expr_propval( struct parser *parser, const struct property *prop ) +{ + struct expr *e = alloc_mem( parser, sizeof *e ); + if (e) + { + e->type = EXPR_PROPVAL; + e->u.propval = prop; + } + return e; +} + +static int wql_error( struct parser *parser, const char *str ); +static int wql_lex( void *val, struct parser *parser ); + +#define PARSER_BUBBLE_UP_VIEW( parser, result, current_view ) \ + *parser->view = current_view; \ + result = current_view + +%} + +%lex-param { struct parser *ctx } +%parse-param { struct parser *ctx } +%error-verbose +%pure-parser + +%union +{ + struct string str; + WCHAR *string; + struct property *proplist; + struct view *view; + struct expr *expr; + int integer; +} + +%token TK_SELECT TK_FROM TK_STAR TK_COMMA TK_DOT TK_IS TK_LP TK_RP TK_NULL TK_FALSE TK_TRUE +%token TK_INTEGER TK_WHERE TK_SPACE TK_MINUS TK_ILLEGAL TK_BY +%token TK_STRING TK_ID + +%type id +%type prop proplist +%type select +%type expr prop_val const_val string_val +%type number + +%left TK_OR +%left TK_AND +%left TK_NOT +%left TK_EQ TK_NE TK_LT TK_GT TK_LE TK_GE TK_LIKE + +%% + +select: + TK_SELECT TK_FROM id + { + HRESULT hr; + struct parser *parser = ctx; + struct view *view; + + hr = create_view( NULL, $3, NULL, &view ); + if (hr != S_OK) + YYABORT; + + PARSER_BUBBLE_UP_VIEW( parser, $$, view ); + } + | TK_SELECT proplist TK_FROM id + { + HRESULT hr; + struct parser *parser = ctx; + struct view *view; + + hr = create_view( $2, $4, NULL, &view ); + if (hr != S_OK) + YYABORT; + + PARSER_BUBBLE_UP_VIEW( parser, $$, view ); + } + | TK_SELECT proplist TK_FROM id TK_WHERE expr + { + HRESULT hr; + struct parser *parser = ctx; + struct view *view; + + hr = create_view( $2, $4, $6, &view ); + if (hr != S_OK) + YYABORT; + + PARSER_BUBBLE_UP_VIEW( parser, $$, view ); + } + ; + +proplist: + prop + | prop TK_COMMA proplist + { + $1->next = $3; + } + | TK_STAR + { + $$ = NULL; + } + ; + +prop: + id TK_DOT id + { + $$ = alloc_property( ctx, $1, $3 ); + if (!$$) + YYABORT; + } + | id + { + $$ = alloc_property( ctx, NULL, $1 ); + if (!$$) + YYABORT; + } + ; + +id: + TK_ID + { + $$ = get_string( ctx, &$1 ); + if (!$$) + YYABORT; + } + ; + +number: + TK_INTEGER + { + $$ = get_int( ctx ); + } + ; + +expr: + TK_LP expr TK_RP + { + $$ = $2; + if (!$$) + YYABORT; + } + | expr TK_AND expr + { + $$ = expr_complex( ctx, $1, OP_AND, $3 ); + if (!$$) + YYABORT; + } + | expr TK_OR expr + { + $$ = expr_complex( ctx, $1, OP_OR, $3 ); + if (!$$) + YYABORT; + } + | TK_NOT expr + { + $$ = expr_unary( ctx, $2, OP_NOT ); + if (!$$) + YYABORT; + } + | prop_val TK_EQ const_val + { + $$ = expr_complex( ctx, $1, OP_EQ, $3 ); + if (!$$) + YYABORT; + } + | prop_val TK_GT const_val + { + $$ = expr_complex( ctx, $1, OP_GT, $3 ); + if (!$$) + YYABORT; + } + | prop_val TK_LT const_val + { + $$ = expr_complex( ctx, $1, OP_LT, $3 ); + if (!$$) + YYABORT; + } + | prop_val TK_LE const_val + { + $$ = expr_complex( ctx, $1, OP_LE, $3 ); + if (!$$) + YYABORT; + } + | prop_val TK_GE const_val + { + $$ = expr_complex( ctx, $1, OP_GE, $3 ); + if (!$$) + YYABORT; + } + | prop_val TK_NE const_val + { + $$ = expr_complex( ctx, $1, OP_NE, $3 ); + if (!$$) + YYABORT; + } + | const_val TK_EQ prop_val + { + $$ = expr_complex( ctx, $1, OP_EQ, $3 ); + if (!$$) + YYABORT; + } + | const_val TK_GT prop_val + { + $$ = expr_complex( ctx, $1, OP_GT, $3 ); + if (!$$) + YYABORT; + } + | const_val TK_LT prop_val + { + $$ = expr_complex( ctx, $1, OP_LT, $3 ); + if (!$$) + YYABORT; + } + | const_val TK_LE prop_val + { + $$ = expr_complex( ctx, $1, OP_LE, $3 ); + if (!$$) + YYABORT; + } + | const_val TK_GE prop_val + { + $$ = expr_complex( ctx, $1, OP_GE, $3 ); + if (!$$) + YYABORT; + } + | const_val TK_NE prop_val + { + $$ = expr_complex( ctx, $1, OP_NE, $3 ); + if (!$$) + YYABORT; + } + | prop_val TK_LIKE string_val + { + $$ = expr_complex( ctx, $1, OP_LIKE, $3 ); + if (!$$) + YYABORT; + } + | prop_val TK_IS TK_NULL + { + $$ = expr_unary( ctx, $1, OP_ISNULL ); + if (!$$) + YYABORT; + } + | prop_val TK_IS TK_NOT TK_NULL + { + $$ = expr_unary( ctx, $1, OP_NOTNULL ); + if (!$$) + YYABORT; + } + ; + +string_val: + TK_STRING + { + $$ = expr_sval( ctx, &$1 ); + if (!$$) + YYABORT; + } + ; + +prop_val: + prop + { + $$ = expr_propval( ctx, $1 ); + if (!$$) + YYABORT; + } + ; + +const_val: + number + { + $$ = expr_ival( ctx, $1 ); + if (!$$) + YYABORT; + } + | TK_STRING + { + $$ = expr_sval( ctx, &$1 ); + if (!$$) + YYABORT; + } + | TK_TRUE + { + $$ = expr_bval( ctx, -1 ); + if (!$$) + YYABORT; + } + | TK_FALSE + { + $$ = expr_bval( ctx, 0 ); + if (!$$) + YYABORT; + } + ; + +%% + +HRESULT parse_query( const WCHAR *str, struct view **view, struct list *mem ) +{ + struct parser parser; + int ret; + + *view = NULL; + + parser.cmd = str; + parser.idx = 0; + parser.len = 0; + parser.error = WBEM_E_INVALID_QUERY; + parser.view = view; + parser.mem = mem; + + ret = wql_parse( &parser ); + TRACE("wql_parse returned %d\n", ret); + if (ret) + { + if (*parser.view) + { + destroy_view( *parser.view ); + *parser.view = NULL; + } + return parser.error; + } + return S_OK; +} + +static const char id_char[] = +{ + 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, + 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, + 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, +}; + +struct keyword +{ + const WCHAR *name; + unsigned int len; + int type; +}; + +#define MAX_TOKEN_LEN 6 + +static const WCHAR andW[] = {'A','N','D'}; +static const WCHAR byW[] = {'B','Y'}; +static const WCHAR falseW[] = {'F','A','L','S','E'}; +static const WCHAR fromW[] = {'F','R','O','M'}; +static const WCHAR isW[] = {'I','S'}; +static const WCHAR likeW[] = {'L','I','K','E'}; +static const WCHAR notW[] = {'N','O','T'}; +static const WCHAR nullW[] = {'N','U','L','L'}; +static const WCHAR orW[] = {'O','R'}; +static const WCHAR selectW[] = {'S','E','L','E','C','T'}; +static const WCHAR trueW[] = {'T','R','U','E'}; +static const WCHAR whereW[] = {'W','H','E','R','E'}; + +static const struct keyword keyword_table[] = +{ + { andW, SIZEOF(andW), TK_AND }, + { byW, SIZEOF(byW), TK_BY }, + { falseW, SIZEOF(falseW), TK_FALSE }, + { fromW, SIZEOF(fromW), TK_FROM }, + { isW, SIZEOF(isW), TK_IS }, + { likeW, SIZEOF(likeW), TK_LIKE }, + { notW, SIZEOF(notW), TK_NOT }, + { nullW, SIZEOF(nullW), TK_NULL }, + { orW, SIZEOF(orW), TK_OR }, + { selectW, SIZEOF(selectW), TK_SELECT }, + { trueW, SIZEOF(trueW), TK_TRUE }, + { whereW, SIZEOF(whereW), TK_WHERE } +}; + +static int cmp_keyword( const void *arg1, const void *arg2 ) +{ + const struct keyword *key1 = arg1, *key2 = arg2; + int len = min( key1->len, key2->len ); + int ret; + + if ((ret = memicmpW( key1->name, key2->name, len ))) return ret; + if (key1->len < key2->len) return -1; + else if (key1->len > key2->len) return 1; + return 0; +} + +static int keyword_type( const WCHAR *str, unsigned int len ) +{ + struct keyword key, *ret; + + if (len > MAX_TOKEN_LEN) return TK_ID; + + key.name = str; + key.len = len; + key.type = 0; + ret = bsearch( &key, keyword_table, SIZEOF(keyword_table), sizeof(struct keyword), cmp_keyword ); + if (ret) return ret->type; + return TK_ID; +} + +static int get_token( const WCHAR *s, int *token ) +{ + int i; + + switch (*s) + { + case ' ': + case '\t': + case '\r': + case '\n': + for (i = 1; isspaceW( s[i] ); i++) {} + *token = TK_SPACE; + return i; + case '-': + if (!s[1]) return -1; + *token = TK_MINUS; + return 1; + case '(': + *token = TK_LP; + return 1; + case ')': + *token = TK_RP; + return 1; + case '*': + *token = TK_STAR; + return 1; + case '=': + *token = TK_EQ; + return 1; + case '<': + if (s[1] == '=' ) + { + *token = TK_LE; + return 2; + } + else if (s[1] == '>') + { + *token = TK_NE; + return 2; + } + else + { + *token = TK_LT; + return 1; + } + case '>': + if (s[1] == '=') + { + *token = TK_GE; + return 2; + } + else + { + *token = TK_GT; + return 1; + } + case '!': + if (s[1] != '=') + { + *token = TK_ILLEGAL; + return 2; + } + else + { + *token = TK_NE; + return 2; + } + case ',': + *token = TK_COMMA; + return 1; + case '\"': + case '\'': + for (i = 1; s[i]; i++) + { + if (s[i] == s[0]) break; + } + if (s[i]) i++; + *token = TK_STRING; + return i; + case '.': + if (!isdigitW( s[1] )) + { + *token = TK_DOT; + return 1; + } + /* fall through */ + case '0': case '1': case '2': case '3': case '4': + case '5': case '6': case '7': case '8': case '9': + *token = TK_INTEGER; + for (i = 1; isdigitW( s[i] ); i++) {} + return i; + default: + if (!id_char[*s]) break; + + for (i = 1; id_char[s[i]]; i++) {} + *token = keyword_type( s, i ); + return i; + } + *token = TK_ILLEGAL; + return 1; +} + +static int wql_lex( void *p, struct parser *parser ) +{ + struct string *str = p; + int token = -1; + do + { + parser->idx += parser->len; + if (!parser->cmd[parser->idx]) return 0; + parser->len = get_token( &parser->cmd[parser->idx], &token ); + if (!parser->len) break; + + str->data = &parser->cmd[parser->idx]; + str->len = parser->len; + } while (token == TK_SPACE); + return token; +} + +static int wql_error( struct parser *parser, const char *str ) +{ + ERR("%s\n", str); + return 0; +} diff --git a/reactos/dll/win32/wmi/CMakeLists.txt b/reactos/dll/win32/wmi/CMakeLists.txt new file mode 100644 index 00000000000..0519d44940e --- /dev/null +++ b/reactos/dll/win32/wmi/CMakeLists.txt @@ -0,0 +1,12 @@ + +spec2def(wmi.dll wmi.spec) + +list(APPEND SOURCE + wmi.rc + ${CMAKE_CURRENT_BINARY_DIR}/wmi.def) + +add_library(wmi SHARED ${SOURCE}) +set_module_type(wmi win32dll ENTRYPOINT 0 ) +add_importlibs(wmi advapi32) +add_dependencies(wmi psdk) +add_cd_file(TARGET wmi DESTINATION reactos/system32 FOR all) diff --git a/reactos/dll/win32/wmi/wmi.rc b/reactos/dll/win32/wmi/wmi.rc new file mode 100644 index 00000000000..ab10b3c30a3 --- /dev/null +++ b/reactos/dll/win32/wmi/wmi.rc @@ -0,0 +1,5 @@ +#define REACTOS_VERSION_DLL +#define REACTOS_STR_FILE_DESCRIPTION "WMI DC and DP functionality" +#define REACTOS_STR_INTERNAL_NAME "wmi" +#define REACTOS_STR_ORIGINAL_FILENAME "wmi.dll" +#include diff --git a/reactos/dll/win32/wmi/wmi.spec b/reactos/dll/win32/wmi/wmi.spec new file mode 100644 index 00000000000..4291d4d910e --- /dev/null +++ b/reactos/dll/win32/wmi/wmi.spec @@ -0,0 +1,45 @@ +@ stdcall CloseTrace(int64) advapi32.CloseTrace +@ stdcall ControlTraceA(int64 str ptr long) advapi32.ControlTraceA +@ stdcall ControlTraceW(int64 wstr ptr long) advapi32.ControlTraceW +@ stdcall CreateTraceInstanceId(long ptr) advapi32.CreateTraceInstanceId +@ stdcall EnableTrace(long long long ptr int64) advapi32.EnableTrace +@ stdcall GetTraceEnableFlags(int64) advapi32.GetTraceEnableFlags +@ stdcall GetTraceEnableLevel(int64) advapi32.GetTraceEnableLevel +@ stdcall -ret64 GetTraceLoggerHandle(ptr) advapi32.GetTraceLoggerHandle +@ stdcall -ret64 OpenTraceA(ptr) advapi32.OpenTraceA +@ stdcall -ret64 OpenTraceW(ptr) advapi32.OpenTraceW +@ stdcall ProcessTrace(ptr long ptr ptr) advapi32.ProcessTrace +@ stdcall QueryAllTracesA(ptr long ptr) advapi32.QueryAllTracesA +@ stdcall QueryAllTracesW(ptr long ptr) advapi32.QueryAllTracesW +@ stdcall RegisterTraceGuidsA(ptr ptr ptr long ptr str str ptr) advapi32.RegisterTraceGuidsA +@ stdcall RegisterTraceGuidsW(ptr ptr ptr long ptr wstr wstr ptr) advapi32.RegisterTraceGuidsW +@ stdcall RemoveTraceCallback(ptr) advapi32.RemoveTraceCallback +@ stdcall SetTraceCallback(ptr ptr) advapi32.SetTraceCallback +@ stdcall StartTraceA(ptr str ptr) advapi32.StartTraceA +@ stdcall StartTraceW(ptr wstr ptr) advapi32.StartTraceW +@ stdcall TraceEvent(int64 ptr) advapi32.TraceEvent +@ stdcall TraceEventInstance(int64 ptr ptr ptr) advapi32.TraceEventInstance +@ stdcall UnregisterTraceGuids(int64) advapi32.UnregisterTraceGuids +@ stdcall WmiCloseBlock() advapi32.WmiCloseBlock +@ stdcall WmiDevInstToInstanceNameA() advapi32.WmiDevInstToInstanceNameA +@ stdcall WmiDevInstToInstanceNameW() advapi32.WmiDevInstToInstanceNameW +@ stdcall WmiEnumerateGuids() advapi32.WmiEnumerateGuids +@ stdcall WmiExecuteMethodA() advapi32.WmiExecuteMethodA +@ stdcall WmiExecuteMethodW() advapi32.WmiExecuteMethodW +@ stdcall WmiFileHandleToInstanceNameA() advapi32.WmiFileHandleToInstanceNameA +@ stdcall WmiFileHandleToInstanceNameW() advapi32.WmiFileHandleToInstanceNameW +@ stdcall WmiFreeBuffer() advapi32.WmiFreeBuffer +@ stdcall WmiMofEnumerateResourcesA() advapi32.WmiMofEnumerateResourcesA +@ stdcall WmiMofEnumerateResourcesW() advapi32.WmiMofEnumerateResourcesW +@ stdcall WmiNotificationRegistrationA() advapi32.WmiNotificationRegistrationA +@ stdcall WmiNotificationRegistrationW() advapi32.WmiNotificationRegistrationW +@ stdcall WmiOpenBlock() advapi32.WmiOpenBlock +@ stdcall WmiQueryAllDataA() advapi32.WmiQueryAllDataA +@ stdcall WmiQueryAllDataW() advapi32.WmiQueryAllDataW +@ stdcall WmiQueryGuidInformation() advapi32.WmiQueryGuidInformation +@ stdcall WmiQuerySingleInstanceA() advapi32.WmiQuerySingleInstanceA +@ stdcall WmiQuerySingleInstanceW() advapi32.WmiQuerySingleInstanceW +@ stdcall WmiSetSingleInstanceA() advapi32.WmiSetSingleInstanceA +@ stdcall WmiSetSingleInstanceW() advapi32.WmiSetSingleInstanceW +@ stdcall WmiSetSingleItemA() advapi32.WmiSetSingleItemA +@ stdcall WmiSetSingleItemW() advapi32.WmiSetSingleItemW diff --git a/reactos/dll/win32/wmiutils/CMakeLists.txt b/reactos/dll/win32/wmiutils/CMakeLists.txt new file mode 100644 index 00000000000..f0542a1ffac --- /dev/null +++ b/reactos/dll/win32/wmiutils/CMakeLists.txt @@ -0,0 +1,17 @@ + +add_definitions(-D__WINESRC__) + +include_directories(${REACTOS_SOURCE_DIR}/sdk/include/reactos/wine) +spec2def(wmiutils.dll wmiutils.spec) + +list(APPEND SOURCE + main.c + path.c + statuscode.c + ${CMAKE_CURRENT_BINARY_DIR}/wmiutils.def) + +add_library(wmiutils SHARED ${SOURCE} wmiutils.rc) +set_module_type(wmiutils win32dll) +target_link_libraries(wmiutils wine) +add_importlibs(wmiutils oleaut32 msvcrt kernel32 ntdll) +add_cd_file(TARGET wmiutils DESTINATION reactos/system32/wbem FOR all) diff --git a/reactos/dll/win32/wmiutils/main.c b/reactos/dll/win32/wmiutils/main.c new file mode 100644 index 00000000000..89fd26b248d --- /dev/null +++ b/reactos/dll/win32/wmiutils/main.c @@ -0,0 +1,171 @@ +/* + * Copyright 2009 Hans Leidekker for CodeWeavers + * + * 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 "config.h" +#include + +#define COBJMACROS + +#include "windef.h" +#include "winbase.h" +#include "winuser.h" +#include "initguid.h" +#include "objbase.h" +#include "wbemcli.h" +#include "wmiutils.h" +#include "rpcproxy.h" + +#include "wine/debug.h" +#include "wmiutils_private.h" + +WINE_DEFAULT_DEBUG_CHANNEL(wmiutils); + +static HINSTANCE instance; + +typedef HRESULT (*fnCreateInstance)( LPVOID *ppObj ); + +typedef struct +{ + IClassFactory IClassFactory_iface; + fnCreateInstance pfnCreateInstance; +} wmiutils_cf; + +static inline wmiutils_cf *impl_from_IClassFactory( IClassFactory *iface ) +{ + return CONTAINING_RECORD(iface, wmiutils_cf, IClassFactory_iface); +} + +static HRESULT WINAPI wmiutils_cf_QueryInterface( IClassFactory *iface, REFIID riid, LPVOID *ppobj ) +{ + if (IsEqualGUID(riid, &IID_IUnknown) || + IsEqualGUID(riid, &IID_IClassFactory)) + { + IClassFactory_AddRef( iface ); + *ppobj = iface; + return S_OK; + } + FIXME("interface %s not implemented\n", debugstr_guid(riid)); + return E_NOINTERFACE; +} + +static ULONG WINAPI wmiutils_cf_AddRef( IClassFactory *iface ) +{ + return 2; +} + +static ULONG WINAPI wmiutils_cf_Release( IClassFactory *iface ) +{ + return 1; +} + +static HRESULT WINAPI wmiutils_cf_CreateInstance( IClassFactory *iface, LPUNKNOWN pOuter, + REFIID riid, LPVOID *ppobj ) +{ + wmiutils_cf *This = impl_from_IClassFactory( iface ); + HRESULT r; + IUnknown *punk; + + TRACE("%p %s %p\n", pOuter, debugstr_guid(riid), ppobj); + + *ppobj = NULL; + + if (pOuter) + return CLASS_E_NOAGGREGATION; + + r = This->pfnCreateInstance( (LPVOID *)&punk ); + if (FAILED(r)) + return r; + + r = IUnknown_QueryInterface( punk, riid, ppobj ); + IUnknown_Release( punk ); + return r; +} + +static HRESULT WINAPI wmiutils_cf_LockServer( IClassFactory *iface, BOOL dolock ) +{ + FIXME("(%p)->(%d)\n", iface, dolock); + return S_OK; +} + +static const struct IClassFactoryVtbl wmiutils_cf_vtbl = +{ + wmiutils_cf_QueryInterface, + wmiutils_cf_AddRef, + wmiutils_cf_Release, + wmiutils_cf_CreateInstance, + wmiutils_cf_LockServer +}; + +static wmiutils_cf status_code_cf = { { &wmiutils_cf_vtbl }, WbemStatusCodeText_create }; +static wmiutils_cf path_cf = { { &wmiutils_cf_vtbl }, WbemPath_create }; + +BOOL WINAPI DllMain( HINSTANCE hinst, DWORD reason, LPVOID lpv ) +{ + switch(reason) + { + case DLL_WINE_PREATTACH: + return FALSE; /* prefer native version */ + case DLL_PROCESS_ATTACH: + instance = hinst; + DisableThreadLibraryCalls( hinst ); + break; + } + return TRUE; +} + +HRESULT WINAPI DllGetClassObject( REFCLSID rclsid, REFIID iid, LPVOID *ppv ) +{ + IClassFactory *cf = NULL; + + TRACE("%s %s %p\n", debugstr_guid(rclsid), debugstr_guid(iid), ppv); + + if (IsEqualGUID( rclsid, &CLSID_WbemStatusCode )) + { + cf = &status_code_cf.IClassFactory_iface; + } + else if (IsEqualGUID( rclsid, &CLSID_WbemDefPath )) + { + cf = &path_cf.IClassFactory_iface; + } + if (!cf) return CLASS_E_CLASSNOTAVAILABLE; + return IClassFactory_QueryInterface( cf, iid, ppv ); +} + +/*********************************************************************** + * DllCanUnloadNow (WMIUTILS.@) + */ +HRESULT WINAPI DllCanUnloadNow( void ) +{ + return S_FALSE; +} + +/*********************************************************************** + * DllRegisterServer (WMIUTILS.@) + */ +HRESULT WINAPI DllRegisterServer(void) +{ + return __wine_register_resources( instance ); +} + +/*********************************************************************** + * DllUnregisterServer (WMIUTILS.@) + */ +HRESULT WINAPI DllUnregisterServer(void) +{ + return __wine_unregister_resources( instance ); +} diff --git a/reactos/dll/win32/wmiutils/path.c b/reactos/dll/win32/wmiutils/path.c new file mode 100644 index 00000000000..61386d95f32 --- /dev/null +++ b/reactos/dll/win32/wmiutils/path.c @@ -0,0 +1,1294 @@ +/* + * Copyright 2012 Hans Leidekker for CodeWeavers + * + * 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 + */ + +#define COBJMACROS + +#include "config.h" +#include + +#include "windef.h" +#include "winbase.h" +#include "ole2.h" +#include "wbemcli.h" +#include "wmiutils.h" + +#include "wine/debug.h" +#include "wmiutils_private.h" + +WINE_DEFAULT_DEBUG_CHANNEL(wmiutils); + +struct keylist +{ + IWbemPathKeyList IWbemPathKeyList_iface; + IWbemPath *parent; + LONG refs; +}; + +struct key +{ + WCHAR *name; + int len_name; + WCHAR *value; + int len_value; +}; + +struct path +{ + IWbemPath IWbemPath_iface; + LONG refs; + CRITICAL_SECTION cs; + WCHAR *text; + int len_text; + WCHAR *server; + int len_server; + WCHAR **namespaces; + int *len_namespaces; + int num_namespaces; + WCHAR *class; + int len_class; + struct key *keys; + unsigned int num_keys; + ULONGLONG flags; +}; + +static inline struct keylist *impl_from_IWbemPathKeyList( IWbemPathKeyList *iface ) +{ + return CONTAINING_RECORD(iface, struct keylist, IWbemPathKeyList_iface); +} + +static inline struct path *impl_from_IWbemPath( IWbemPath *iface ) +{ + return CONTAINING_RECORD(iface, struct path, IWbemPath_iface); +} + +static ULONG WINAPI keylist_AddRef( + IWbemPathKeyList *iface ) +{ + struct keylist *keylist = impl_from_IWbemPathKeyList( iface ); + return InterlockedIncrement( &keylist->refs ); +} + +static ULONG WINAPI keylist_Release( + IWbemPathKeyList *iface ) +{ + struct keylist *keylist = impl_from_IWbemPathKeyList( iface ); + LONG refs = InterlockedDecrement( &keylist->refs ); + if (!refs) + { + TRACE("destroying %p\n", keylist); + IWbemPath_Release( keylist->parent ); + heap_free( keylist ); + } + return refs; +} + +static HRESULT WINAPI keylist_QueryInterface( + IWbemPathKeyList *iface, + REFIID riid, + void **ppvObject ) +{ + struct keylist *keylist = impl_from_IWbemPathKeyList( iface ); + + TRACE("%p, %s, %p\n", keylist, debugstr_guid(riid), ppvObject); + + if (IsEqualGUID( riid, &IID_IWbemPathKeyList ) || + IsEqualGUID( riid, &IID_IUnknown )) + { + *ppvObject = iface; + } + else + { + FIXME("interface %s not implemented\n", debugstr_guid(riid)); + return E_NOINTERFACE; + } + IWbemPathKeyList_AddRef( iface ); + return S_OK; +} + +static HRESULT WINAPI keylist_GetCount( + IWbemPathKeyList *iface, + ULONG *puKeyCount ) +{ + struct keylist *keylist = impl_from_IWbemPathKeyList( iface ); + struct path *parent = impl_from_IWbemPath( keylist->parent ); + + TRACE("%p, %p\n", iface, puKeyCount); + + if (!puKeyCount) return WBEM_E_INVALID_PARAMETER; + + EnterCriticalSection( &parent->cs ); + + *puKeyCount = parent->num_keys; + + LeaveCriticalSection( &parent->cs ); + return S_OK; +} + +static HRESULT WINAPI keylist_SetKey( + IWbemPathKeyList *iface, + LPCWSTR wszName, + ULONG uFlags, + ULONG uCimType, + LPVOID pKeyVal ) +{ + FIXME("%p, %s, 0x%x, %u, %p\n", iface, debugstr_w(wszName), uFlags, uCimType, pKeyVal); + return E_NOTIMPL; +} + +static HRESULT WINAPI keylist_SetKey2( + IWbemPathKeyList *iface, + LPCWSTR wszName, + ULONG uFlags, + ULONG uCimType, + VARIANT *pKeyVal ) +{ + FIXME("%p, %s, 0x%x, %u, %p\n", iface, debugstr_w(wszName), uFlags, uCimType, pKeyVal); + return E_NOTIMPL; +} + +static HRESULT WINAPI keylist_GetKey( + IWbemPathKeyList *iface, + ULONG uKeyIx, + ULONG uFlags, + ULONG *puNameBufSize, + LPWSTR pszKeyName, + ULONG *puKeyValBufSize, + LPVOID pKeyVal, + ULONG *puApparentCimType ) +{ + FIXME("%p, %u, 0x%x, %p, %p, %p, %p, %p\n", iface, uKeyIx, uFlags, puNameBufSize, + pszKeyName, puKeyValBufSize, pKeyVal, puApparentCimType); + return E_NOTIMPL; +} + +static HRESULT WINAPI keylist_GetKey2( + IWbemPathKeyList *iface, + ULONG uKeyIx, + ULONG uFlags, + ULONG *puNameBufSize, + LPWSTR pszKeyName, + VARIANT *pKeyValue, + ULONG *puApparentCimType ) +{ + FIXME("%p, %u, 0x%x, %p, %p, %p, %p\n", iface, uKeyIx, uFlags, puNameBufSize, + pszKeyName, pKeyValue, puApparentCimType); + return E_NOTIMPL; +} + +static HRESULT WINAPI keylist_RemoveKey( + IWbemPathKeyList *iface, + LPCWSTR wszName, + ULONG uFlags ) +{ + FIXME("%p, %s, 0x%x\n", iface, debugstr_w(wszName), uFlags); + return E_NOTIMPL; +} + +static void free_keys( struct key *keys, unsigned int count ) +{ + unsigned int i; + + for (i = 0; i < count; i++) + { + heap_free( keys[i].name ); + heap_free( keys[i].value ); + } + heap_free( keys ); +} + +static HRESULT WINAPI keylist_RemoveAllKeys( + IWbemPathKeyList *iface, + ULONG uFlags ) +{ + struct keylist *keylist = impl_from_IWbemPathKeyList( iface ); + struct path *parent = impl_from_IWbemPath( keylist->parent ); + + TRACE("%p, 0x%x\n", iface, uFlags); + + if (uFlags) return WBEM_E_INVALID_PARAMETER; + + EnterCriticalSection( &parent->cs ); + + free_keys( parent->keys, parent->num_keys ); + parent->num_keys = 0; + parent->keys = NULL; + + LeaveCriticalSection( &parent->cs ); + return S_OK; +} + +static HRESULT WINAPI keylist_MakeSingleton( + IWbemPathKeyList *iface, + boolean bSet ) +{ + FIXME("%p, %d\n", iface, bSet); + return E_NOTIMPL; +} + +static HRESULT WINAPI keylist_GetInfo( + IWbemPathKeyList *iface, + ULONG uRequestedInfo, + ULONGLONG *puResponse ) +{ + FIXME("%p, %u, %p\n", iface, uRequestedInfo, puResponse); + return E_NOTIMPL; +} + +static HRESULT WINAPI keylist_GetText( + IWbemPathKeyList *iface, + LONG lFlags, + ULONG *puBuffLength, + LPWSTR pszText ) +{ + FIXME("%p, 0x%x, %p, %p\n", iface, lFlags, puBuffLength, pszText); + return E_NOTIMPL; +} + +static const struct IWbemPathKeyListVtbl keylist_vtbl = +{ + keylist_QueryInterface, + keylist_AddRef, + keylist_Release, + keylist_GetCount, + keylist_SetKey, + keylist_SetKey2, + keylist_GetKey, + keylist_GetKey2, + keylist_RemoveKey, + keylist_RemoveAllKeys, + keylist_MakeSingleton, + keylist_GetInfo, + keylist_GetText +}; + +static HRESULT WbemPathKeyList_create( IWbemPath *parent, LPVOID *ppObj ) +{ + struct keylist *keylist; + + TRACE("%p\n", ppObj); + + if (!(keylist = heap_alloc( sizeof(*keylist) ))) return E_OUTOFMEMORY; + + keylist->IWbemPathKeyList_iface.lpVtbl = &keylist_vtbl; + keylist->refs = 1; + keylist->parent = parent; + IWbemPath_AddRef( keylist->parent ); + + *ppObj = &keylist->IWbemPathKeyList_iface; + + TRACE("returning iface %p\n", *ppObj); + return S_OK; +} + +static void init_path( struct path *path ) +{ + path->text = NULL; + path->len_text = 0; + path->server = NULL; + path->len_server = 0; + path->namespaces = NULL; + path->len_namespaces = NULL; + path->num_namespaces = 0; + path->class = NULL; + path->len_class = 0; + path->keys = NULL; + path->num_keys = 0; + path->flags = 0; +} + +static void clear_path( struct path *path ) +{ + unsigned int i; + + heap_free( path->text ); + heap_free( path->server ); + for (i = 0; i < path->num_namespaces; i++) heap_free( path->namespaces[i] ); + heap_free( path->namespaces ); + heap_free( path->len_namespaces ); + heap_free( path->class ); + free_keys( path->keys, path->num_keys ); + init_path( path ); +} + +static ULONG WINAPI path_AddRef( + IWbemPath *iface ) +{ + struct path *path = impl_from_IWbemPath( iface ); + return InterlockedIncrement( &path->refs ); +} + +static ULONG WINAPI path_Release( + IWbemPath *iface ) +{ + struct path *path = impl_from_IWbemPath( iface ); + LONG refs = InterlockedDecrement( &path->refs ); + if (!refs) + { + TRACE("destroying %p\n", path); + clear_path( path ); + path->cs.DebugInfo->Spare[0] = 0; + DeleteCriticalSection( &path->cs ); + heap_free( path ); + } + return refs; +} + +static HRESULT WINAPI path_QueryInterface( + IWbemPath *iface, + REFIID riid, + void **ppvObject ) +{ + struct path *path = impl_from_IWbemPath( iface ); + + TRACE("%p, %s, %p\n", path, debugstr_guid( riid ), ppvObject ); + + if ( IsEqualGUID( riid, &IID_IWbemPath ) || + IsEqualGUID( riid, &IID_IUnknown ) ) + { + *ppvObject = iface; + } + else + { + FIXME("interface %s not implemented\n", debugstr_guid(riid)); + return E_NOINTERFACE; + } + IWbemPath_AddRef( iface ); + return S_OK; +} + +static HRESULT parse_key( struct key *key, const WCHAR *str, unsigned int *ret_len ) +{ + const WCHAR *p, *q; + unsigned int len; + + p = q = str; + while (*q && *q != '=') + { + if (*q == ',' || isspaceW( *q )) return WBEM_E_INVALID_PARAMETER; + q++; + } + len = q - p; + if (!(key->name = heap_alloc( (len + 1) * sizeof(WCHAR) ))) return E_OUTOFMEMORY; + memcpy( key->name, p, len * sizeof(WCHAR) ); + key->name[len] = 0; + key->len_name = len; + + p = ++q; + if (!*p || *p == ',' || isspaceW( *p )) return WBEM_E_INVALID_PARAMETER; + + while (*q && *q != ',') q++; + len = q - p; + if (!(key->value = heap_alloc( (len + 1) * sizeof(WCHAR) ))) return E_OUTOFMEMORY; + memcpy( key->value, p, len * sizeof(WCHAR) ); + key->value[len] = 0; + key->len_value = len; + + *ret_len = q - str; + if (*q == ',') (*ret_len)++; + return S_OK; +} + +static HRESULT parse_text( struct path *path, ULONG mode, const WCHAR *text ) +{ + HRESULT hr = E_OUTOFMEMORY; + const WCHAR *p, *q; + unsigned int i, len; + + p = q = text; + if ((p[0] == '\\' && p[1] == '\\') || (p[0] == '/' && p[1] == '/')) + { + p += 2; + q = p; + while (*q && *q != '\\' && *q != '/') q++; + len = q - p; + if (!(path->server = heap_alloc( (len + 1) * sizeof(WCHAR) ))) goto done; + memcpy( path->server, p, len * sizeof(WCHAR) ); + path->server[len] = 0; + path->len_server = len; + path->flags |= WBEMPATH_INFO_PATH_HAD_SERVER; + } + p = q; + if (strchrW( p, '\\' ) || strchrW( p, '/' )) + { + if (*q != '\\' && *q != '/' && *q != ':') + { + path->num_namespaces = 1; + q++; + } + while (*q && *q != ':') + { + if (*q == '\\' || *q == '/') path->num_namespaces++; + q++; + } + } + if (path->num_namespaces) + { + if (!(path->namespaces = heap_alloc( path->num_namespaces * sizeof(WCHAR *) ))) goto done; + if (!(path->len_namespaces = heap_alloc( path->num_namespaces * sizeof(int) ))) goto done; + + i = 0; + q = p; + if (*q && *q != '\\' && *q != '/' && *q != ':') + { + p = q; + while (*p && *p != '\\' && *p != '/' && *p != ':') p++; + len = p - q; + if (!(path->namespaces[i] = heap_alloc( (len + 1) * sizeof(WCHAR) ))) goto done; + memcpy( path->namespaces[i], q, len * sizeof(WCHAR) ); + path->namespaces[i][len] = 0; + path->len_namespaces[i] = len; + q = p; + i++; + } + while (*q && *q != ':') + { + if (*q == '\\' || *q == '/') + { + p = q + 1; + while (*p && *p != '\\' && *p != '/' && *p != ':') p++; + len = p - q - 1; + if (!(path->namespaces[i] = heap_alloc( (len + 1) * sizeof(WCHAR) ))) goto done; + memcpy( path->namespaces[i], q + 1, len * sizeof(WCHAR) ); + path->namespaces[i][len] = 0; + path->len_namespaces[i] = len; + i++; + } + q++; + } + } + if (*q == ':') q++; + p = q; + while (*q && *q != '.') q++; + len = q - p; + if (!(path->class = heap_alloc( (len + 1) * sizeof(WCHAR) ))) goto done; + memcpy( path->class, p, len * sizeof(WCHAR) ); + path->class[len] = 0; + path->len_class = len; + + if (*q == '.') + { + p = ++q; + path->num_keys++; + while (*q) + { + if (*q == ',') path->num_keys++; + q++; + } + if (!(path->keys = heap_alloc_zero( path->num_keys * sizeof(struct key) ))) goto done; + i = 0; + q = p; + while (*q) + { + if (i >= path->num_keys) break; + hr = parse_key( &path->keys[i], q, &len ); + if (hr != S_OK) goto done; + q += len; + i++; + } + } + hr = S_OK; + +done: + if (hr != S_OK) clear_path( path ); + else path->flags |= WBEMPATH_INFO_CIM_COMPLIANT | WBEMPATH_INFO_V2_COMPLIANT; + return hr; +} + +static HRESULT WINAPI path_SetText( + IWbemPath *iface, + ULONG uMode, + LPCWSTR pszPath) +{ + struct path *path = impl_from_IWbemPath( iface ); + HRESULT hr = S_OK; + int len; + + TRACE("%p, %u, %s\n", iface, uMode, debugstr_w(pszPath)); + + if (!uMode || !pszPath) return WBEM_E_INVALID_PARAMETER; + + EnterCriticalSection( &path->cs ); + + clear_path( path ); + if (!pszPath[0]) goto done; + if ((hr = parse_text( path, uMode, pszPath )) != S_OK) goto done; + + len = strlenW( pszPath ); + if (!(path->text = heap_alloc( (len + 1) * sizeof(WCHAR) ))) + { + clear_path( path ); + hr = E_OUTOFMEMORY; + goto done; + } + strcpyW( path->text, pszPath ); + path->len_text = len; + +done: + LeaveCriticalSection( &path->cs ); + return hr; +} + +static WCHAR *build_namespace( struct path *path, int *len, BOOL leading_slash ) +{ + WCHAR *ret, *p; + int i; + + *len = 0; + for (i = 0; i < path->num_namespaces; i++) + { + if (i > 0 || leading_slash) *len += 1; + *len += path->len_namespaces[i]; + } + if (!(p = ret = heap_alloc( (*len + 1) * sizeof(WCHAR) ))) return NULL; + for (i = 0; i < path->num_namespaces; i++) + { + if (i > 0 || leading_slash) *p++ = '\\'; + memcpy( p, path->namespaces[i], path->len_namespaces[i] * sizeof(WCHAR) ); + p += path->len_namespaces[i]; + } + *p = 0; + return ret; +} + +static WCHAR *build_server( struct path *path, int *len ) +{ + WCHAR *ret, *p; + + *len = 0; + if (path->len_server) *len += 2 + path->len_server; + else *len += 3; + if (!(p = ret = heap_alloc( (*len + 1) * sizeof(WCHAR) ))) return NULL; + if (path->len_server) + { + p[0] = p[1] = '\\'; + strcpyW( p + 2, path->server ); + } + else + { + p[0] = p[1] = '\\'; + p[2] = '.'; + p[3] = 0; + } + return ret; +} + +static WCHAR *build_keylist( struct path *path, int *len ) +{ + WCHAR *ret, *p; + unsigned int i; + + *len = 0; + for (i = 0; i < path->num_keys; i++) + { + if (i > 0) *len += 1; + *len += path->keys[i].len_name + path->keys[i].len_value + 1; + } + if (!(p = ret = heap_alloc( (*len + 1) * sizeof(WCHAR) ))) return NULL; + for (i = 0; i < path->num_keys; i++) + { + if (i > 0) *p++ = ','; + memcpy( p, path->keys[i].name, path->keys[i].len_name * sizeof(WCHAR) ); + p += path->keys[i].len_name; + *p++ = '='; + memcpy( p, path->keys[i].value, path->keys[i].len_value * sizeof(WCHAR) ); + p += path->keys[i].len_value; + } + *p = 0; + return ret; +} + +static WCHAR *build_path( struct path *path, LONG flags, int *len ) +{ + *len = 0; + switch (flags) + { + case 0: + { + int len_namespace, len_keylist; + WCHAR *ret, *namespace = build_namespace( path, &len_namespace, FALSE ); + WCHAR *keylist = build_keylist( path, &len_keylist ); + + if (!namespace || !keylist) + { + heap_free( namespace ); + heap_free( keylist ); + return NULL; + } + *len = len_namespace; + if (path->len_class) + { + *len += path->len_class + 1; + if (path->num_keys) *len += len_keylist + 1; + } + if (!(ret = heap_alloc( (*len + 1) * sizeof(WCHAR) ))) + { + heap_free( namespace ); + heap_free( keylist ); + return NULL; + } + strcpyW( ret, namespace ); + if (path->len_class) + { + ret[len_namespace] = ':'; + strcpyW( ret + len_namespace + 1, path->class ); + if (path->num_keys) + { + ret[len_namespace + path->len_class + 1] = '.'; + strcpyW( ret + len_namespace + path->len_class + 2, keylist ); + } + } + heap_free( namespace ); + heap_free( keylist ); + return ret; + + } + case WBEMPATH_GET_RELATIVE_ONLY: + { + int len_keylist; + WCHAR *ret, *keylist; + + if (!path->len_class) return NULL; + if (!(keylist = build_keylist( path, &len_keylist ))) return NULL; + + *len = path->len_class; + if (path->num_keys) *len += len_keylist + 1; + if (!(ret = heap_alloc( (*len + 1) * sizeof(WCHAR) ))) + { + heap_free( keylist ); + return NULL; + } + strcpyW( ret, path->class ); + if (path->num_keys) + { + ret[path->len_class] = '.'; + strcpyW( ret + path->len_class + 1, keylist ); + } + heap_free( keylist ); + return ret; + } + case WBEMPATH_GET_SERVER_TOO: + { + int len_namespace, len_server, len_keylist; + WCHAR *p, *ret, *namespace = build_namespace( path, &len_namespace, TRUE ); + WCHAR *server = build_server( path, &len_server ); + WCHAR *keylist = build_keylist( path, &len_keylist ); + + if (!namespace || !server || !keylist) + { + heap_free( namespace ); + heap_free( server ); + heap_free( keylist ); + return NULL; + } + *len = len_namespace + len_server; + if (path->len_class) + { + *len += path->len_class + 1; + if (path->num_keys) *len += len_keylist + 1; + } + if (!(p = ret = heap_alloc( (*len + 1) * sizeof(WCHAR) ))) + { + heap_free( namespace ); + heap_free( server ); + heap_free( keylist ); + return NULL; + } + strcpyW( p, server ); + p += len_server; + strcpyW( p, namespace ); + p += len_namespace; + if (path->len_class) + { + *p++ = ':'; + strcpyW( p, path->class ); + if (path->num_keys) + { + p[path->len_class] = '.'; + strcpyW( p + path->len_class + 1, keylist ); + } + } + heap_free( namespace ); + heap_free( server ); + heap_free( keylist ); + return ret; + } + case WBEMPATH_GET_SERVER_AND_NAMESPACE_ONLY: + { + int len_namespace, len_server; + WCHAR *p, *ret, *namespace = build_namespace( path, &len_namespace, TRUE ); + WCHAR *server = build_server( path, &len_server ); + + if (!namespace || !server) + { + heap_free( namespace ); + heap_free( server ); + return NULL; + } + *len = len_namespace + len_server; + if (!(p = ret = heap_alloc( (*len + 1) * sizeof(WCHAR) ))) + { + heap_free( namespace ); + heap_free( server ); + return NULL; + } + strcpyW( p, server ); + p += len_server; + strcpyW( p, namespace ); + heap_free( namespace ); + heap_free( server ); + return ret; + } + case WBEMPATH_GET_NAMESPACE_ONLY: + return build_namespace( path, len, FALSE ); + + case WBEMPATH_GET_ORIGINAL: + if (!path->len_text) return NULL; + *len = path->len_text; + return strdupW( path->text ); + + default: + ERR("unhandled flags 0x%x\n", flags); + return NULL; + } +} + +static HRESULT WINAPI path_GetText( + IWbemPath *iface, + LONG lFlags, + ULONG *puBufferLength, + LPWSTR pszText) +{ + struct path *path = impl_from_IWbemPath( iface ); + HRESULT hr = S_OK; + WCHAR *str; + int len; + + TRACE("%p, 0x%x, %p, %p\n", iface, lFlags, puBufferLength, pszText); + + if (!puBufferLength) return WBEM_E_INVALID_PARAMETER; + + EnterCriticalSection( &path->cs ); + + str = build_path( path, lFlags, &len ); + if (*puBufferLength < len + 1) + { + *puBufferLength = len + 1; + goto done; + } + if (!pszText) + { + hr = WBEM_E_INVALID_PARAMETER; + goto done; + } + if (str) strcpyW( pszText, str ); + else pszText[0] = 0; + *puBufferLength = len + 1; + + TRACE("returning %s\n", debugstr_w(pszText)); + +done: + heap_free( str ); + LeaveCriticalSection( &path->cs ); + return hr; +} + +static HRESULT WINAPI path_GetInfo( + IWbemPath *iface, + ULONG info, + ULONGLONG *response) +{ + struct path *path = impl_from_IWbemPath( iface ); + + TRACE("%p, %u, %p\n", iface, info, response); + + if (info || !response) return WBEM_E_INVALID_PARAMETER; + + FIXME("some flags are not implemented\n"); + + EnterCriticalSection( &path->cs ); + + *response = path->flags; + if (!path->server || (path->len_server == 1 && path->server[0] == '.')) + *response |= WBEMPATH_INFO_ANON_LOCAL_MACHINE; + else + *response |= WBEMPATH_INFO_HAS_MACHINE_NAME; + + if (!path->class) + *response |= WBEMPATH_INFO_SERVER_NAMESPACE_ONLY; + else + { + *response |= WBEMPATH_INFO_HAS_SUBSCOPES; + if (path->num_keys) + *response |= WBEMPATH_INFO_IS_INST_REF; + else + *response |= WBEMPATH_INFO_IS_CLASS_REF; + } + + LeaveCriticalSection( &path->cs ); + return S_OK; +} + +static HRESULT WINAPI path_SetServer( + IWbemPath *iface, + LPCWSTR name) +{ + struct path *path = impl_from_IWbemPath( iface ); + static const ULONGLONG flags = + WBEMPATH_INFO_PATH_HAD_SERVER | WBEMPATH_INFO_V1_COMPLIANT | + WBEMPATH_INFO_V2_COMPLIANT | WBEMPATH_INFO_CIM_COMPLIANT; + WCHAR *server; + + TRACE("%p, %s\n", iface, debugstr_w(name)); + + EnterCriticalSection( &path->cs ); + + if (name) + { + if (!(server = strdupW( name ))) + { + LeaveCriticalSection( &path->cs ); + return WBEM_E_OUT_OF_MEMORY; + } + heap_free( path->server ); + path->server = server; + path->len_server = strlenW( path->server ); + path->flags |= flags; + } + else + { + heap_free( path->server ); + path->server = NULL; + path->len_server = 0; + path->flags &= ~flags; + } + + LeaveCriticalSection( &path->cs ); + return S_OK; +} + +static HRESULT WINAPI path_GetServer( + IWbemPath *iface, + ULONG *len, + LPWSTR name) +{ + struct path *path = impl_from_IWbemPath( iface ); + + TRACE("%p, %p, %p\n", iface, len, name); + + if (!len || (*len && !name)) return WBEM_E_INVALID_PARAMETER; + + EnterCriticalSection( &path->cs ); + + if (!path->server) + { + LeaveCriticalSection( &path->cs ); + return WBEM_E_NOT_AVAILABLE; + } + if (*len > path->len_server) strcpyW( name, path->server ); + *len = path->len_server + 1; + + LeaveCriticalSection( &path->cs ); + return S_OK; +} + +static HRESULT WINAPI path_GetNamespaceCount( + IWbemPath *iface, + ULONG *puCount) +{ + struct path *path = impl_from_IWbemPath( iface ); + + TRACE("%p, %p\n", iface, puCount); + + if (!puCount) return WBEM_E_INVALID_PARAMETER; + + EnterCriticalSection( &path->cs ); + *puCount = path->num_namespaces; + LeaveCriticalSection( &path->cs ); + return S_OK; +} + +static HRESULT WINAPI path_SetNamespaceAt( + IWbemPath *iface, + ULONG idx, + LPCWSTR name) +{ + struct path *path = impl_from_IWbemPath( iface ); + static const ULONGLONG flags = + WBEMPATH_INFO_V1_COMPLIANT | WBEMPATH_INFO_V2_COMPLIANT | + WBEMPATH_INFO_CIM_COMPLIANT; + int i, *tmp_len; + WCHAR **tmp, *new; + DWORD size; + + TRACE("%p, %u, %s\n", iface, idx, debugstr_w(name)); + + EnterCriticalSection( &path->cs ); + + if (idx > path->num_namespaces || !name) + { + LeaveCriticalSection( &path->cs ); + return WBEM_E_INVALID_PARAMETER; + } + if (!(new = strdupW( name ))) + { + LeaveCriticalSection( &path->cs ); + return WBEM_E_OUT_OF_MEMORY; + } + size = (path->num_namespaces + 1) * sizeof(WCHAR *); + if (path->namespaces) tmp = heap_realloc( path->namespaces, size ); + else tmp = heap_alloc( size ); + if (!tmp) + { + heap_free( new ); + LeaveCriticalSection( &path->cs ); + return WBEM_E_OUT_OF_MEMORY; + } + path->namespaces = tmp; + size = (path->num_namespaces + 1) * sizeof(int); + if (path->len_namespaces) tmp_len = heap_realloc( path->len_namespaces, size ); + else tmp_len = heap_alloc( size ); + if (!tmp_len) + { + heap_free( new ); + LeaveCriticalSection( &path->cs ); + return WBEM_E_OUT_OF_MEMORY; + } + path->len_namespaces = tmp_len; + for (i = idx; i < path->num_namespaces; i++) + { + path->namespaces[i + 1] = path->namespaces[i]; + path->len_namespaces[i + 1] = path->len_namespaces[i]; + } + path->namespaces[idx] = new; + path->len_namespaces[idx] = strlenW( new ); + path->num_namespaces++; + path->flags |= flags; + + LeaveCriticalSection( &path->cs ); + return S_OK; +} + +static HRESULT WINAPI path_GetNamespaceAt( + IWbemPath *iface, + ULONG idx, + ULONG *len, + LPWSTR name) +{ + struct path *path = impl_from_IWbemPath( iface ); + + TRACE("%p, %u, %p, %p\n", iface, idx, len, name); + + EnterCriticalSection( &path->cs ); + + if (!len || (*len && !name) || idx >= path->num_namespaces) + { + LeaveCriticalSection( &path->cs ); + return WBEM_E_INVALID_PARAMETER; + } + if (*len > path->len_namespaces[idx]) strcpyW( name, path->namespaces[idx] ); + *len = path->len_namespaces[idx] + 1; + + LeaveCriticalSection( &path->cs ); + return S_OK; +} + +static HRESULT WINAPI path_RemoveNamespaceAt( + IWbemPath *iface, + ULONG idx) +{ + struct path *path = impl_from_IWbemPath( iface ); + + TRACE("%p, %u\n", iface, idx); + + EnterCriticalSection( &path->cs ); + + if (idx >= path->num_namespaces) + { + LeaveCriticalSection( &path->cs ); + return WBEM_E_INVALID_PARAMETER; + } + heap_free( path->namespaces[idx] ); + while (idx < path->num_namespaces - 1) + { + path->namespaces[idx] = path->namespaces[idx + 1]; + path->len_namespaces[idx] = path->len_namespaces[idx + 1]; + idx++; + } + path->num_namespaces--; + + LeaveCriticalSection( &path->cs ); + return S_OK; +} + +static HRESULT WINAPI path_RemoveAllNamespaces( + IWbemPath *iface) +{ + struct path *path = impl_from_IWbemPath( iface ); + int i; + + TRACE("%p\n", iface); + + EnterCriticalSection( &path->cs ); + + for (i = 0; i < path->num_namespaces; i++) heap_free( path->namespaces[i] ); + path->num_namespaces = 0; + heap_free( path->namespaces ); + path->namespaces = NULL; + heap_free( path->len_namespaces ); + path->len_namespaces = NULL; + + LeaveCriticalSection( &path->cs ); + return S_OK; +} + +static HRESULT WINAPI path_GetScopeCount( + IWbemPath *iface, + ULONG *puCount) +{ + FIXME("%p, %p\n", iface, puCount); + return E_NOTIMPL; +} + +static HRESULT WINAPI path_SetScope( + IWbemPath *iface, + ULONG uIndex, + LPWSTR pszClass) +{ + FIXME("%p, %u, %s\n", iface, uIndex, debugstr_w(pszClass)); + return E_NOTIMPL; +} + +static HRESULT WINAPI path_SetScopeFromText( + IWbemPath *iface, + ULONG uIndex, + LPWSTR pszText) +{ + FIXME("%p, %u, %s\n", iface, uIndex, debugstr_w(pszText)); + return E_NOTIMPL; +} + +static HRESULT WINAPI path_GetScope( + IWbemPath *iface, + ULONG uIndex, + ULONG *puClassNameBufSize, + LPWSTR pszClass, + IWbemPathKeyList **pKeyList) +{ + FIXME("%p, %u, %p, %p, %p\n", iface, uIndex, puClassNameBufSize, pszClass, pKeyList); + return E_NOTIMPL; +} + +static HRESULT WINAPI path_GetScopeAsText( + IWbemPath *iface, + ULONG uIndex, + ULONG *puTextBufSize, + LPWSTR pszText) +{ + FIXME("%p, %u, %p, %p\n", iface, uIndex, puTextBufSize, pszText); + return E_NOTIMPL; +} + +static HRESULT WINAPI path_RemoveScope( + IWbemPath *iface, + ULONG uIndex) +{ + FIXME("%p, %u\n", iface, uIndex); + return E_NOTIMPL; +} + +static HRESULT WINAPI path_RemoveAllScopes( + IWbemPath *iface) +{ + FIXME("%p\n", iface); + return E_NOTIMPL; +} + +static HRESULT WINAPI path_SetClassName( + IWbemPath *iface, + LPCWSTR name) +{ + struct path *path = impl_from_IWbemPath( iface ); + WCHAR *class; + + TRACE("%p, %s\n", iface, debugstr_w(name)); + + if (!name) return WBEM_E_INVALID_PARAMETER; + if (!(class = strdupW( name ))) return WBEM_E_OUT_OF_MEMORY; + + EnterCriticalSection( &path->cs ); + + heap_free( path->class ); + path->class = class; + path->len_class = strlenW( path->class ); + path->flags |= WBEMPATH_INFO_V2_COMPLIANT | WBEMPATH_INFO_CIM_COMPLIANT; + + LeaveCriticalSection( &path->cs ); + return S_OK; +} + +static HRESULT WINAPI path_GetClassName( + IWbemPath *iface, + ULONG *len, + LPWSTR name) +{ + struct path *path = impl_from_IWbemPath( iface ); + + TRACE("%p, %p, %p\n", iface, len, name); + + if (!len || (*len && !name)) return WBEM_E_INVALID_PARAMETER; + + EnterCriticalSection( &path->cs ); + + if (!path->class) + { + LeaveCriticalSection( &path->cs ); + return WBEM_E_INVALID_OBJECT_PATH; + } + if (*len > path->len_class) strcpyW( name, path->class ); + *len = path->len_class + 1; + + LeaveCriticalSection( &path->cs ); + return S_OK; +} + +static HRESULT WINAPI path_GetKeyList( + IWbemPath *iface, + IWbemPathKeyList **pOut) +{ + struct path *path = impl_from_IWbemPath( iface ); + HRESULT hr; + + TRACE("%p, %p\n", iface, pOut); + + EnterCriticalSection( &path->cs ); + + if (!path->class) + { + LeaveCriticalSection( &path->cs ); + return WBEM_E_INVALID_PARAMETER; + } + hr = WbemPathKeyList_create( iface, (void **)pOut ); + + LeaveCriticalSection( &path->cs ); + return hr; +} + +static HRESULT WINAPI path_CreateClassPart( + IWbemPath *iface, + LONG lFlags, + LPCWSTR Name) +{ + FIXME("%p, 0x%x, %s\n", iface, lFlags, debugstr_w(Name)); + return E_NOTIMPL; +} + +static HRESULT WINAPI path_DeleteClassPart( + IWbemPath *iface, + LONG lFlags) +{ + FIXME("%p, 0x%x\n", iface, lFlags); + return E_NOTIMPL; +} + +static BOOL WINAPI path_IsRelative( + IWbemPath *iface, + LPWSTR wszMachine, + LPWSTR wszNamespace) +{ + FIXME("%p, %s, %s\n", iface, debugstr_w(wszMachine), debugstr_w(wszNamespace)); + return FALSE; +} + +static BOOL WINAPI path_IsRelativeOrChild( + IWbemPath *iface, + LPWSTR wszMachine, + LPWSTR wszNamespace, + LONG lFlags) +{ + FIXME("%p, %s, %s, 0x%x\n", iface, debugstr_w(wszMachine), debugstr_w(wszNamespace), lFlags); + return FALSE; +} + +static BOOL WINAPI path_IsLocal( + IWbemPath *iface, + LPCWSTR wszMachine) +{ + FIXME("%p, %s\n", iface, debugstr_w(wszMachine)); + return FALSE; +} + +static BOOL WINAPI path_IsSameClassName( + IWbemPath *iface, + LPCWSTR wszClass) +{ + FIXME("%p, %s\n", iface, debugstr_w(wszClass)); + return FALSE; +} + +static const struct IWbemPathVtbl path_vtbl = +{ + path_QueryInterface, + path_AddRef, + path_Release, + path_SetText, + path_GetText, + path_GetInfo, + path_SetServer, + path_GetServer, + path_GetNamespaceCount, + path_SetNamespaceAt, + path_GetNamespaceAt, + path_RemoveNamespaceAt, + path_RemoveAllNamespaces, + path_GetScopeCount, + path_SetScope, + path_SetScopeFromText, + path_GetScope, + path_GetScopeAsText, + path_RemoveScope, + path_RemoveAllScopes, + path_SetClassName, + path_GetClassName, + path_GetKeyList, + path_CreateClassPart, + path_DeleteClassPart, + path_IsRelative, + path_IsRelativeOrChild, + path_IsLocal, + path_IsSameClassName +}; + +HRESULT WbemPath_create( LPVOID *ppObj ) +{ + struct path *path; + + TRACE("%p\n", ppObj); + + if (!(path = heap_alloc( sizeof(*path) ))) return E_OUTOFMEMORY; + + path->IWbemPath_iface.lpVtbl = &path_vtbl; + path->refs = 1; + InitializeCriticalSection( &path->cs ); + path->cs.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": wmiutils_path.cs"); + init_path( path ); + + *ppObj = &path->IWbemPath_iface; + + TRACE("returning iface %p\n", *ppObj); + return S_OK; +} diff --git a/reactos/dll/win32/wmiutils/statuscode.c b/reactos/dll/win32/wmiutils/statuscode.c new file mode 100644 index 00000000000..719f3af8b5d --- /dev/null +++ b/reactos/dll/win32/wmiutils/statuscode.c @@ -0,0 +1,150 @@ +/* + * Copyright 2009 Hans Leidekker for CodeWeavers + * + * 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 + */ + +#define COBJMACROS + +#include "config.h" +#include +#include + +#include "windef.h" +#include "winbase.h" +#include "ole2.h" +#include "wbemcli.h" + +#include "wine/debug.h" +#include "wine/unicode.h" +#include "wmiutils_private.h" + +WINE_DEFAULT_DEBUG_CHANNEL(wmiutils); + +typedef struct status_code +{ + IWbemStatusCodeText IWbemStatusCodeText_iface; + LONG refs; +} status_code; + +static inline status_code *impl_from_IWbemStatusCodeText( IWbemStatusCodeText *iface ) +{ + return CONTAINING_RECORD(iface, status_code, IWbemStatusCodeText_iface); +} + +static ULONG WINAPI status_code_AddRef( + IWbemStatusCodeText *iface ) +{ + status_code *status_code = impl_from_IWbemStatusCodeText( iface ); + return InterlockedIncrement( &status_code->refs ); +} + +static ULONG WINAPI status_code_Release( + IWbemStatusCodeText *iface ) +{ + status_code *status_code = impl_from_IWbemStatusCodeText( iface ); + LONG refs = InterlockedDecrement( &status_code->refs ); + if (!refs) + { + TRACE("destroying %p\n", status_code); + heap_free( status_code ); + } + return refs; +} + +static HRESULT WINAPI status_code_QueryInterface( + IWbemStatusCodeText *iface, + REFIID riid, + void **ppvObject ) +{ + status_code *This = impl_from_IWbemStatusCodeText( iface ); + + TRACE("%p %s %p\n", This, debugstr_guid( riid ), ppvObject ); + + if ( IsEqualGUID( riid, &IID_IWbemStatusCodeText ) || + IsEqualGUID( riid, &IID_IUnknown ) ) + { + *ppvObject = iface; + } + else + { + FIXME("interface %s not implemented\n", debugstr_guid(riid)); + return E_NOINTERFACE; + } + IWbemStatusCodeText_AddRef( iface ); + return S_OK; +} + +static HRESULT WINAPI status_code_GetErrorCodeText( + IWbemStatusCodeText *iface, + HRESULT res, + LCID lcid, + LONG flags, + BSTR *text ) +{ + static const WCHAR fmt[] = + {'E','r','r','o','r',' ','c','o','d','e',':',' ','0','x','%','0','8','x',0}; + WCHAR msg[32]; + + FIXME("%p, 0x%08x, 0x%04x, 0x%08x, %p\n", iface, res, lcid, flags, text); + + sprintfW(msg, fmt, res); + *text = SysAllocString(msg); + return WBEM_S_NO_ERROR; +} + +static HRESULT WINAPI status_code_GetFacilityCodeText( + IWbemStatusCodeText *iface, + HRESULT res, + LCID lcid, + LONG flags, + BSTR *text ) +{ + static const WCHAR fmt[] = + {'F','a','c','i','l','i','t','y',' ','c','o','d','e',':',' ','0','x','%','0','8','x',0}; + WCHAR msg[32]; + + FIXME("%p, 0x%08x, 0x%04x, 0x%08x, %p\n", iface, res, lcid, flags, text); + + sprintfW(msg, fmt, res); + *text = SysAllocString(msg); + return WBEM_S_NO_ERROR; +} + +static const struct IWbemStatusCodeTextVtbl status_code_vtbl = +{ + status_code_QueryInterface, + status_code_AddRef, + status_code_Release, + status_code_GetErrorCodeText, + status_code_GetFacilityCodeText +}; + +HRESULT WbemStatusCodeText_create( LPVOID *ppObj ) +{ + status_code *sc; + + TRACE("(%p)\n", ppObj); + + if (!(sc = heap_alloc( sizeof(*sc) ))) return E_OUTOFMEMORY; + + sc->IWbemStatusCodeText_iface.lpVtbl = &status_code_vtbl; + sc->refs = 1; + + *ppObj = &sc->IWbemStatusCodeText_iface; + + TRACE("returning iface %p\n", *ppObj); + return S_OK; +} diff --git a/reactos/dll/win32/wmiutils/wmiutils.rc b/reactos/dll/win32/wmiutils/wmiutils.rc new file mode 100644 index 00000000000..46ae13bcaa2 --- /dev/null +++ b/reactos/dll/win32/wmiutils/wmiutils.rc @@ -0,0 +1,2 @@ +/* @makedep: wmiutils_classes.rgs */ +1 WINE_REGISTRY wmiutils_classes.rgs diff --git a/reactos/dll/win32/wmiutils/wmiutils.spec b/reactos/dll/win32/wmiutils/wmiutils.spec new file mode 100644 index 00000000000..b16365d0c9f --- /dev/null +++ b/reactos/dll/win32/wmiutils/wmiutils.spec @@ -0,0 +1,4 @@ +@ stdcall -private DllCanUnloadNow() +@ stdcall -private DllGetClassObject(ptr ptr ptr) +@ stdcall -private DllRegisterServer() +@ stdcall -private DllUnregisterServer() diff --git a/reactos/dll/win32/wmiutils/wmiutils_classes.idl b/reactos/dll/win32/wmiutils/wmiutils_classes.idl new file mode 100644 index 00000000000..80b46d5952f --- /dev/null +++ b/reactos/dll/win32/wmiutils/wmiutils_classes.idl @@ -0,0 +1,33 @@ +/* + * COM Classes for wmiutils + * + * Copyright 2010 Alexandre Julliard + * + * 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 + */ + +#pragma makedep register + +[ + threading(both), + uuid(cf4cc405-e2c5-4ddd-b3ce-5e7582d8c9fa) +] +coclass WbemDefPath { interface IWbemPath; } + +[ + threading(both), + uuid(eb87e1bd-3233-11d2-aec9-00c04fb68820) +] +coclass WbemStatusCode { interface IWbemStatusCodeText; } diff --git a/reactos/dll/win32/wmiutils/wmiutils_classes.rgs b/reactos/dll/win32/wmiutils/wmiutils_classes.rgs new file mode 100644 index 00000000000..0f06db380fa --- /dev/null +++ b/reactos/dll/win32/wmiutils/wmiutils_classes.rgs @@ -0,0 +1,17 @@ +HKCR +{ + NoRemove Interface + { + } + NoRemove CLSID + { + '{CF4CC405-E2C5-4DDD-B3CE-5E7582D8C9FA}' = s 'WbemDefPath' + { + InprocServer32 = s '%MODULE%' { val ThreadingModel = s 'Both' } + } + '{EB87E1BD-3233-11D2-AEC9-00C04FB68820}' = s 'WbemStatusCode' + { + InprocServer32 = s '%MODULE%' { val ThreadingModel = s 'Both' } + } + } +} \ No newline at end of file diff --git a/reactos/dll/win32/wmiutils/wmiutils_private.h b/reactos/dll/win32/wmiutils/wmiutils_private.h new file mode 100644 index 00000000000..2b76f712e71 --- /dev/null +++ b/reactos/dll/win32/wmiutils/wmiutils_private.h @@ -0,0 +1,53 @@ +/* + * Copyright 2009 Hans Leidekker for CodeWeavers + * + * 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/unicode.h" + +HRESULT WbemPath_create(LPVOID *) DECLSPEC_HIDDEN; +HRESULT WbemStatusCodeText_create(LPVOID *) DECLSPEC_HIDDEN; + +static void *heap_alloc( size_t len ) __WINE_ALLOC_SIZE(1); +static inline void *heap_alloc( size_t len ) +{ + return HeapAlloc( GetProcessHeap(), 0, len ); +} + +static void *heap_alloc_zero( size_t len ) __WINE_ALLOC_SIZE(1); +static inline void *heap_alloc_zero( size_t len ) +{ + return HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, len ); +} + +static void *heap_realloc( void *mem, size_t len ) __WINE_ALLOC_SIZE(2); +static inline void *heap_realloc( void *mem, size_t len ) +{ + return HeapReAlloc( GetProcessHeap(), 0, mem, len ); +} + +static inline BOOL heap_free( void *mem ) +{ + return HeapFree( GetProcessHeap(), 0, mem ); +} + +static inline WCHAR *strdupW( const WCHAR *src ) +{ + WCHAR *dst; + if (!src) return NULL; + if ((dst = heap_alloc( (strlenW( src ) + 1) * sizeof(WCHAR) ))) strcpyW( dst, src ); + return dst; +} diff --git a/reactos/media/doc/README.WINE b/reactos/media/doc/README.WINE index 65b33d83c0b..8f60802ee67 100644 --- a/reactos/media/doc/README.WINE +++ b/reactos/media/doc/README.WINE @@ -21,11 +21,6 @@ reactos/sdk/tools/wpp # Synced to WineStaging-1.9.11 The following libraries are shared with Wine. -reactos/base/wmi/wbemdisp # Synced to WineStaging-1.9.16 -reactos/base/wmi/wbemprox # Synced to WineStaging-1.9.23 -reactos/base/wmi/wmi # Synced to WineStaging-1.9.11 -reactos/base/wmi/wmiutils # Synced to WineStaging-1.9.11 - reactos/dll/directx/wine/amstream # Synced to WineStaging-1.9.23 reactos/dll/directx/wine/d3d8 # Synced to WineStaging-1.9.4 reactos/dll/directx/wine/d3d9 # Synced to WineStaging-1.9.4 @@ -199,6 +194,8 @@ reactos/dll/win32/uxtheme # Forked reactos/dll/win32/vbscript # Synced to WineStaging-1.9.23 reactos/dll/win32/version # Synced to WineStaging-1.9.11 reactos/dll/win32/vssapi # Synced to WineStaging-1.9.11 +reactos/dll/win32/wbemdisp # Synced to WineStaging-1.9.16 +reactos/dll/win32/wbemprox # Synced to WineStaging-1.9.23 reactos/dll/win32/windowscodecs # Synced to WineStaging-1.9.23 reactos/dll/win32/windowscodecsext # Synced to WineStaging-1.9.11 reactos/dll/win32/winemp3.acm # Synced to WineStaging-1.9.23 @@ -211,6 +208,8 @@ reactos/dll/win32/winmm/wavemap # Forked at Wine-20050628 reactos/dll/win32/winscard # Synced to WineStaging-1.9.11 reactos/dll/win32/wintrust # Synced to WineStaging-1.9.23 reactos/dll/win32/wldap32 # Synced to WineStaging-1.9.11 +reactos/dll/win32/wmi # Synced to WineStaging-1.9.11 +reactos/dll/win32/wmiutils # Synced to WineStaging-1.9.11 reactos/dll/win32/wmvcore # Synced to WineStaging-1.9.11 reactos/dll/win32/wshom.ocx # Synced to WineStaging-1.9.11 reactos/dll/win32/wtsapi32 # Synced to WineStaging-1.9.11 @@ -231,6 +230,7 @@ reactos/base/applications/cmdutils/cscript # Synced to WineStaging-1.9.11 reactos/base/applications/cmdutils/reg # Synced to WineStaging-1.9.16 reactos/base/applications/cmdutils/schtasks # Synced to WineStaging-1.9.14 reactos/base/applications/cmdutils/taskkill # Synced to WineStaging-1.9.11 +reactos/base/applications/cmdutils/wmic # Synced to WineStaging-1.9.11 reactos/base/applications/cmdutils/wscript # Synced to WineStaging-1.9.16 reactos/base/applications/cmdutils/xcopy # Synced to WineStaging-1.9.11 reactos/base/applications/games/winmine # Synced to WineStaging-1.9.16 with our own resources. @@ -244,10 +244,6 @@ reactos/base/applications/write # Synced to WineStaging-1.9.16 reactos/base/services/rpcss # Synced to WineStaging-1.9.16 reactos/base/system/expand # Synced to WineStaging-1.9.11 reactos/base/system/msiexec # Synced to WineStaging-1.9.11 - -reactos/base/wmi/mofcomp # Synced to Wine-2.2 -reactos/base/wmi/wmic # Synced to WineStaging-1.9.11 - reactos/modules/rosapps/winfile # Autosync In addition the following libs, dlls and source files are mostly based on code ported