* See the COPYING file in the top-level directory.
*/
-#include <stdio.h>
-#include <string.h>
+#include "qemu/osdep.h"
#include "vss-common.h"
-#include "inc/win2003/vscoordint.h"
-
-#include <comadmin.h>
+#ifdef HAVE_VSS_SDK
+#include <vscoordint.h>
+#else
+#include <vsadmin.h>
+#endif
+#include "install.h"
#include <wbemidl.h>
#include <comdef.h>
#include <comutil.h>
+#include <sddl.h>
+#include <winsvc.h>
+
+#define BUFFER_SIZE 1024
extern HINSTANCE g_hinstDll;
* If text doesn't contains '(', negative precision is given, which is
* treated as though it were missing.
*/
- char *msg = NULL, *nul = strchr(text, '(');
+ char *msg = NULL;
+ const char *nul = strchr(text, '(');
int len = nul ? nul - text : -1;
FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
return hr;
}
+/* Acquire group or user name by SID */
+static HRESULT getNameByStringSID(
+ const wchar_t *sid, LPWSTR buffer, LPDWORD bufferLen)
+{
+ HRESULT hr = S_OK;
+ PSID psid = NULL;
+ SID_NAME_USE groupType;
+ DWORD domainNameLen = BUFFER_SIZE;
+ wchar_t domainName[BUFFER_SIZE];
+
+ if (!ConvertStringSidToSidW(sid, &psid)) {
+ hr = HRESULT_FROM_WIN32(GetLastError());
+ goto out;
+ }
+ if (!LookupAccountSidW(NULL, psid, buffer, bufferLen,
+ domainName, &domainNameLen, &groupType)) {
+ hr = HRESULT_FROM_WIN32(GetLastError());
+ /* Fall through and free psid */
+ }
+
+ LocalFree(psid);
+
+out:
+ return hr;
+}
+
/* Find and iterate QGA VSS provider in COM+ Application Catalog */
static HRESULT QGAProviderFind(
HRESULT (*found)(ICatalogCollection *, int, void *), void *arg)
CHAR dllPath[MAX_PATH], tlbPath[MAX_PATH];
bool unregisterOnFailure = false;
int count = 0;
+ DWORD bufferLen = BUFFER_SIZE;
+ wchar_t buffer[BUFFER_SIZE];
+ const wchar_t *administratorsGroupSID = L"S-1-5-32-544";
+ const wchar_t *systemUserSID = L"S-1-5-18";
if (!g_hinstDll) {
errmsg(E_FAIL, "Failed to initialize DLL");
chk(pCatalog->CreateServiceForApplication(
_bstr_t(QGA_PROVIDER_LNAME), _bstr_t(QGA_PROVIDER_LNAME),
- _bstr_t(L"SERVICE_AUTO_START"), _bstr_t(L"SERVICE_ERROR_NORMAL"),
+ _bstr_t(L"SERVICE_DEMAND_START"), _bstr_t(L"SERVICE_ERROR_NORMAL"),
_bstr_t(L""), _bstr_t(L".\\localsystem"), _bstr_t(L""), FALSE));
chk(pCatalog->InstallComponent(_bstr_t(QGA_PROVIDER_LNAME),
_bstr_t(dllPath), _bstr_t(tlbPath),
/* Setup roles of the applicaion */
+ chk(getNameByStringSID(administratorsGroupSID, buffer, &bufferLen));
chk(pApps->GetCollection(_bstr_t(L"Roles"), key,
(IDispatch **)pRoles.replace()));
chk(pRoles->Populate());
chk(pRoles->Add((IDispatch **)pObj.replace()));
- chk(put_Value(pObj, L"Name", L"Administrators"));
+ chk(put_Value(pObj, L"Name", buffer));
chk(put_Value(pObj, L"Description", L"Administrators group"));
chk(pRoles->SaveChanges(&n));
chk(pObj->get_Key(&key));
chk(GetAdminName(&name));
chk(put_Value(pObj, L"User", _bstr_t(".\\") + name));
+ bufferLen = BUFFER_SIZE;
+ chk(getNameByStringSID(systemUserSID, buffer, &bufferLen));
chk(pUsersInRole->Add((IDispatch **)pObj.replace()));
- chk(put_Value(pObj, L"User", L"SYSTEM"));
+ chk(put_Value(pObj, L"User", buffer));
chk(pUsersInRole->SaveChanges(&n));
out:
VSS_PROV_SOFTWARE,
const_cast<WCHAR*>(QGA_PROVIDER_VERSION),
g_gProviderVersion);
+ if (hr == (long int) VSS_E_PROVIDER_ALREADY_REGISTERED) {
+ DllUnregisterServer();
+ hr = pVssAdmin->RegisterProvider(g_gProviderId, CLSID_QGAVSSProvider,
+ const_cast<WCHAR * >
+ (QGA_PROVIDER_LNAME),
+ VSS_PROV_SOFTWARE,
+ const_cast<WCHAR * >
+ (QGA_PROVIDER_VERSION),
+ g_gProviderVersion);
+ }
+
if (FAILED(hr)) {
errmsg_dialog(hr, "RegisterProvider failed");
}
return bstr;
}
}
+
+/* Stop QGA VSS provider service using Winsvc API */
+STDAPI StopService(void)
+{
+ HRESULT hr = S_OK;
+ SC_HANDLE manager = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
+ SC_HANDLE service = NULL;
+
+ if (!manager) {
+ errmsg(E_FAIL, "Failed to open service manager");
+ hr = E_FAIL;
+ goto out;
+ }
+ service = OpenService(manager, QGA_PROVIDER_NAME, SC_MANAGER_ALL_ACCESS);
+
+ if (!service) {
+ errmsg(E_FAIL, "Failed to open service");
+ hr = E_FAIL;
+ goto out;
+ }
+ if (!(ControlService(service, SERVICE_CONTROL_STOP, NULL))) {
+ errmsg(E_FAIL, "Failed to stop service");
+ hr = E_FAIL;
+ }
+
+out:
+ CloseServiceHandle(service);
+ CloseServiceHandle(manager);
+ return hr;
+}