diff --git a/dlls/wiaservc/Makefile.in b/dlls/wiaservc/Makefile.in index 67db9493321..f73e8dd23cb 100644 --- a/dlls/wiaservc/Makefile.in +++ b/dlls/wiaservc/Makefile.in @@ -11,6 +11,8 @@ C_SRCS = \ wiadevmgr.c \ wiaservc_main.c +RC_SRCS = rsrc.rc + @MAKE_DLL_RULES@ @DEPENDENCIES@ # everything below this line is overwritten by make depend diff --git a/dlls/wiaservc/rsrc.rc b/dlls/wiaservc/rsrc.rc new file mode 100644 index 00000000000..d54734b326e --- /dev/null +++ b/dlls/wiaservc/rsrc.rc @@ -0,0 +1,20 @@ +/* + * Copyright 2009 Damjan Jovanovic + * + * 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 + */ + +/* @makedep: wiaservc.inf */ +REGINST REGINST wiaservc.inf diff --git a/dlls/wiaservc/wiaservc.inf b/dlls/wiaservc/wiaservc.inf new file mode 100644 index 00000000000..c181a609083 --- /dev/null +++ b/dlls/wiaservc/wiaservc.inf @@ -0,0 +1,28 @@ +[version] +Signature="$CHICAGO$" + +[RegisterDll] +AddReg = WiaServc.Reg + +[UnregisterDll] +DelReg = WiaServc.Reg + +[WiaServc.Reg] +HKCR,"AppID\%CLSID_WiaDevMgr%",,,"WIA Device Manager" +HKCR,"AppID\%CLSID_WiaDevMgr%","LocalService",,"stisvc" + +HKCR,"CLSID\%CLSID_WiaDevMgr%",,,"WIA Device Manager" +HKCR,"CLSID\%CLSID_WiaDevMgr%","AppID",,"%CLSID_WiaDevMgr%" +HKCR,"CLSID\%CLSID_WiaDevMgr%\ProgID",,,"WiaDevMgr.1" +HKCR,"CLSID\%CLSID_WiaDevMgr%\VersionIndependentProgID",,,"WiaDevMgr" + +HKCR,"WiaDevMgr.1",,,"WIA Device Manager" +HKCR,"WiaDevMgr.1\CLSID",,,"%CLSID_WiaDevMgr%" + +HKCR,"WiaDevMgr",,,"WIA Device Manager" +HKCR,"WiaDevMgr\CLSID",,,"%CLSID_WiaDevMgr%" +HKCR,"WiaDevMgr\CurVer",,,"WiaDevMgr.1" + +HKLM,"Software\Microsoft\Windows NT\CurrentVersion\SvcHost","imgsvc",0x00010000,"StiSvc" + +HKLM,"System\CurrentControlSet\Services\stisvc\Parameters","ServiceDll",0x00020000,"wiaservc.dll" diff --git a/dlls/wiaservc/wiaservc.spec b/dlls/wiaservc/wiaservc.spec index afd2426cc31..510e3e9662b 100644 --- a/dlls/wiaservc/wiaservc.spec +++ b/dlls/wiaservc/wiaservc.spec @@ -1,6 +1,6 @@ @ stdcall -private ServiceMain(long ptr) -@ stub DllRegisterServer -@ stub DllUnregisterServer +@ stdcall -private DllRegisterServer() +@ stdcall -private DllUnregisterServer() @ stub wiasCreateChildAppItem @ stub wiasCreateDrvItem @ stub wiasCreateLogInstance diff --git a/dlls/wiaservc/wiaservc_main.c b/dlls/wiaservc/wiaservc_main.c index 2d30f9d869d..ce979a28c7b 100644 --- a/dlls/wiaservc/wiaservc_main.c +++ b/dlls/wiaservc/wiaservc_main.c @@ -18,6 +18,8 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#include + #include "objbase.h" #include "winuser.h" #include "winreg.h" @@ -28,6 +30,8 @@ #include "wia_lh.h" #include "initguid.h" +#include "wiaservc_private.h" + #include "wine/debug.h" WINE_DEFAULT_DEBUG_CHANNEL(wia); @@ -54,3 +58,116 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) return TRUE; } + +static HRESULT init_register_strtable(STRTABLEA *strtable) +{ +#define CLSID_EXPANSION_ENTRY(id) { "CLSID_" #id, &CLSID_ ## id } + static const struct { + const char *name; + const CLSID *clsid; + } expns[] = { + CLSID_EXPANSION_ENTRY(WiaDevMgr) + }; +#undef CLSID_EXPANSION_ENTRY + static STRENTRYA pse[sizeof expns / sizeof expns[0]]; + DWORD i; + + strtable->cEntries = sizeof pse / sizeof pse[0]; + strtable->pse = pse; + for (i = 0; i < strtable->cEntries; i++) { + static const char dummy_sample[] = "{12345678-1234-1234-1234-123456789012}"; + const CLSID *clsid = expns[i].clsid; + pse[i].pszName = wiaservc_strdup(expns[i].name); + pse[i].pszValue = HeapAlloc(GetProcessHeap(), 0, sizeof dummy_sample); + if (!pse[i].pszName || !pse[i].pszValue) + return E_OUTOFMEMORY; + sprintf(pse[i].pszValue, "{%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}", + clsid->Data1, clsid->Data2, clsid->Data3, clsid->Data4[0], + clsid->Data4[1], clsid->Data4[2], clsid->Data4[3], clsid->Data4[4], + clsid->Data4[5], clsid->Data4[6], clsid->Data4[7]); + } + + return S_OK; +} + +static void cleanup_register_strtable(STRTABLEA *strtable) +{ + DWORD i; + for (i = 0; i < strtable->cEntries; i++) { + HeapFree(GetProcessHeap(), 0, strtable->pse[i].pszName); + HeapFree(GetProcessHeap(), 0, strtable->pse[i].pszValue); + if (!strtable->pse[i].pszName || !strtable->pse[i].pszValue) + return; + } +} + +static HRESULT register_service(BOOL do_register) +{ + static const WCHAR name[] = { 's','t','i','s','v','c', 0 }; + static const WCHAR path[] = { 's','v','c','h','o','s','t','.','e','x','e', + ' ','-','k',' ','i','m','g','s','v','c', 0 }; + SC_HANDLE scm, service; + + scm = OpenSCManagerW(NULL, NULL, SC_MANAGER_ALL_ACCESS); + if (!scm) + return SELFREG_E_CLASS; + + if (do_register) + service = CreateServiceW(scm, name, name, SERVICE_ALL_ACCESS, + SERVICE_WIN32_OWN_PROCESS, + SERVICE_DEMAND_START, SERVICE_ERROR_NORMAL, + path, NULL, NULL, NULL, NULL, NULL); + else + service = OpenServiceW(scm, name, DELETE); + + + CloseServiceHandle(scm); + if (service) + { + if (!do_register) DeleteService(service); + CloseServiceHandle(service); + } + return S_OK; +} + +/* Use an INF file to register or unregister the DLL */ +static HRESULT register_server(BOOL do_register) +{ + HRESULT hr; + STRTABLEA strtable; + HMODULE hAdvpack; + HRESULT (WINAPI *pRegInstall)(HMODULE hm, LPCSTR pszSection, const STRTABLEA* pstTable); + static const WCHAR wszAdvpack[] = {'a','d','v','p','a','c','k','.','d','l','l',0}; + + TRACE("(%x)\n", do_register); + + hr = register_service(do_register); + if (FAILED(hr)) { + ERR("register_service failed: %d\n", GetLastError()); + return hr; + } + + hAdvpack = LoadLibraryW(wszAdvpack); + pRegInstall = (void *)GetProcAddress(hAdvpack, "RegInstall"); + + hr = init_register_strtable(&strtable); + if (SUCCEEDED(hr)) + hr = pRegInstall(hInst, do_register ? "RegisterDll" : "UnregisterDll", + &strtable); + cleanup_register_strtable(&strtable); + + if (FAILED(hr)) + ERR("RegInstall failed: %08x\n", hr); + + return hr; +} + +HRESULT WINAPI DllRegisterServer(void) +{ + return register_server(TRUE); +} + +HRESULT WINAPI DllUnregisterServer(void) +{ + return register_server(FALSE); +} diff --git a/dlls/wiaservc/wiaservc_private.h b/dlls/wiaservc/wiaservc_private.h index d822958feff..103281966e7 100644 --- a/dlls/wiaservc/wiaservc_private.h +++ b/dlls/wiaservc/wiaservc_private.h @@ -36,4 +36,13 @@ typedef struct HRESULT wiadevmgr_Constructor(IUnknown *pUnkOuter, LPVOID *ppObj); +/* Little helper functions */ +static inline char * +wiaservc_strdup(const char *s) +{ + size_t n = strlen(s) + 1; + char *d = HeapAlloc(GetProcessHeap(), 0, n); + return d ? memcpy(d, s, n) : NULL; +} + #endif /* __WIASERVC_PRIVATE__ */ diff --git a/tools/wine.inf.in b/tools/wine.inf.in index ac8742bfb69..15509192ba9 100644 --- a/tools/wine.inf.in +++ b/tools/wine.inf.in @@ -2425,6 +2425,7 @@ HKLM,%CurrentVersion%\Telephony\Country List\998,"SameAreaRule",,"G" 11,,sti.dll,1 11,,urlmon.dll,1 11,,wbemprox.dll,1 +11,,wiaservc.dll,1 11,,windowscodecs.dll,1 11,,wintrust.dll,1 11,,wmiutils.dll,1