/*********************************************************************** * unregister_interfaces */ static HRESULT unregister_interfaces(struct regsvr_interface const *list) { LONG res = ERROR_SUCCESS; HKEY interface_key; res = RegOpenKeyExW(HKEY_CLASSES_ROOT, interface_keyname, 0, KEY_READ | KEY_WRITE, &interface_key); if (res == ERROR_FILE_NOT_FOUND) return S_OK; if (res != ERROR_SUCCESS) goto error_return; for (; res == ERROR_SUCCESS && list->iid; ++list) { WCHAR buf[39]; StringFromGUID2(list->iid, buf, 39); res = RegDeleteTreeW(interface_key, buf); if (res == ERROR_FILE_NOT_FOUND) res = ERROR_SUCCESS; } RegCloseKey(interface_key); error_return: return res != ERROR_SUCCESS ? HRESULT_FROM_WIN32(res) : S_OK; }
/*********************************************************************** * unregister_mediatypes_parsing */ static HRESULT unregister_mediatypes_parsing(struct regsvr_mediatype_parsing const *list) { LONG res; HKEY mediatype_key; HKEY majortype_key; WCHAR buf[39]; res = RegOpenKeyExW(HKEY_CLASSES_ROOT, mediatype_name, 0, KEY_READ | KEY_WRITE, &mediatype_key); if (res == ERROR_FILE_NOT_FOUND) return S_OK; if (res != ERROR_SUCCESS) return HRESULT_FROM_WIN32(res); for (; res == ERROR_SUCCESS && list->majortype; ++list) { StringFromGUID2(list->majortype, buf, 39); res = RegOpenKeyExW(mediatype_key, buf, 0, KEY_READ | KEY_WRITE, &majortype_key); if (res == ERROR_FILE_NOT_FOUND) { res = ERROR_SUCCESS; continue; } if (res != ERROR_SUCCESS) break; StringFromGUID2(list->subtype, buf, 39); res = RegDeleteTreeW(majortype_key, buf); if (res == ERROR_FILE_NOT_FOUND) res = ERROR_SUCCESS; /* Removed majortype key if there is no more subtype key */ res = RegDeleteKeyW(majortype_key, 0); if (res == ERROR_ACCESS_DENIED) res = ERROR_SUCCESS; RegCloseKey(majortype_key); } RegCloseKey(mediatype_key); return res != ERROR_SUCCESS ? HRESULT_FROM_WIN32(res) : S_OK; }
/*********************************************************************** * unregister_coclasses */ static HRESULT unregister_coclasses(struct regsvr_coclass const *list) { LONG res = ERROR_SUCCESS; HKEY coclass_key; res = RegOpenKeyExW(HKEY_CLASSES_ROOT, clsid_keyname, 0, KEY_READ | KEY_WRITE, &coclass_key); if (res == ERROR_FILE_NOT_FOUND) return S_OK; if (res != ERROR_SUCCESS) goto error_return; for (; res == ERROR_SUCCESS && list->clsid; ++list) { WCHAR buf[39]; StringFromGUID2(list->clsid, buf, 39); res = RegDeleteTreeW(coclass_key, buf); if (res == ERROR_FILE_NOT_FOUND) res = ERROR_SUCCESS; if (res != ERROR_SUCCESS) goto error_close_coclass_key; if (list->progid) { res = RegDeleteTreeA(HKEY_CLASSES_ROOT, list->progid); if (res == ERROR_FILE_NOT_FOUND) res = ERROR_SUCCESS; if (res != ERROR_SUCCESS) goto error_close_coclass_key; } if (list->viprogid) { res = RegDeleteTreeA(HKEY_CLASSES_ROOT, list->viprogid); if (res == ERROR_FILE_NOT_FOUND) res = ERROR_SUCCESS; if (res != ERROR_SUCCESS) goto error_close_coclass_key; } } error_close_coclass_key: RegCloseKey(coclass_key); error_return: return res != ERROR_SUCCESS ? HRESULT_FROM_WIN32(res) : S_OK; }
UINT MSIREG_DeleteUserDataProductKey(LPCWSTR szProduct) { UINT rc; WCHAR squished_pc[GUID_SIZE]; WCHAR keypath[0x200]; LPWSTR usersid; TRACE("%s\n", debugstr_w(szProduct)); if (!squash_guid(szProduct, squished_pc)) return ERROR_FUNCTION_FAILED; TRACE("squished (%s)\n", debugstr_w(squished_pc)); rc = get_user_sid(&usersid); if (rc != ERROR_SUCCESS || !usersid) { ERR("Failed to retrieve user SID: %d\n", rc); return rc; } sprintfW(keypath, szUserDataProd_fmt, usersid, squished_pc); LocalFree(usersid); return RegDeleteTreeW(HKEY_LOCAL_MACHINE, keypath); }
/********************************************************************** * DEVENUM_CreateSpecialCategories (INTERNAL) * * Creates the keys in the registry for the dynamic categories */ static HRESULT DEVENUM_CreateSpecialCategories(void) { HRESULT res; WCHAR szDSoundNameFormat[MAX_PATH + 1]; WCHAR szDSoundName[MAX_PATH + 1]; DWORD iDefaultDevice = -1; UINT numDevs; IFilterMapper2 * pMapper = NULL; REGFILTER2 rf2; REGFILTERPINS2 rfp2; WCHAR path[MAX_PATH]; HKEY basekey; if (DEVENUM_populate_handle) return S_OK; DEVENUM_populate_handle = CreateEventW(NULL, TRUE, FALSE, DEVENUM_populate_handle_nameW); if (GetLastError() == ERROR_ALREADY_EXISTS) { /* Webcams can take some time to scan if the driver is badly written and it enables them, * so have a 10 s timeout here */ if (WaitForSingleObject(DEVENUM_populate_handle, 10000) == WAIT_TIMEOUT) WARN("Waiting for object timed out\n"); TRACE("No need to rescan\n"); return S_OK; } TRACE("Scanning for devices\n"); /* Since devices can change between session, for example because you just plugged in a webcam * or switched from pulseaudio to alsa, delete all old devices first */ if (SUCCEEDED(DEVENUM_GetCategoryKey(&CLSID_AudioRendererCategory, &basekey, path, MAX_PATH))) RegDeleteTreeW(basekey, path); if (SUCCEEDED(DEVENUM_GetCategoryKey(&CLSID_AudioInputDeviceCategory, &basekey, path, MAX_PATH))) RegDeleteTreeW(basekey, path); if (SUCCEEDED(DEVENUM_GetCategoryKey(&CLSID_VideoInputDeviceCategory, &basekey, path, MAX_PATH))) RegDeleteTreeW(basekey, path); if (SUCCEEDED(DEVENUM_GetCategoryKey(&CLSID_MidiRendererCategory, &basekey, path, MAX_PATH))) RegDeleteTreeW(basekey, path); rf2.dwVersion = 2; rf2.dwMerit = MERIT_PREFERRED; rf2.u.s1.cPins2 = 1; rf2.u.s1.rgPins2 = &rfp2; rfp2.cInstances = 1; rfp2.nMediums = 0; rfp2.lpMedium = NULL; rfp2.clsPinCategory = &IID_NULL; if (!LoadStringW(DEVENUM_hInstance, IDS_DEVENUM_DS, szDSoundNameFormat, sizeof(szDSoundNameFormat)/sizeof(szDSoundNameFormat[0])-1)) { ERR("Couldn't get string resource (GetLastError() is %d)\n", GetLastError()); return HRESULT_FROM_WIN32(GetLastError()); } res = CoCreateInstance(&CLSID_FilterMapper2, NULL, CLSCTX_INPROC, &IID_IFilterMapper2, (void **) &pMapper); /* * Fill in info for devices */ if (SUCCEEDED(res)) { UINT i; WAVEOUTCAPSW wocaps; WAVEINCAPSW wicaps; MIDIOUTCAPSW mocaps; REGPINTYPES * pTypes; numDevs = waveOutGetNumDevs(); res = DEVENUM_CreateAMCategoryKey(&CLSID_AudioRendererCategory); if (FAILED(res)) /* can't register any devices in this category */ numDevs = 0; rfp2.dwFlags = REG_PINFLAG_B_RENDERER; for (i = 0; i < numDevs; i++) { if (waveOutGetDevCapsW(i, &wocaps, sizeof(WAVEOUTCAPSW)) == MMSYSERR_NOERROR) { IMoniker * pMoniker = NULL; rfp2.nMediaTypes = 1; pTypes = CoTaskMemAlloc(rfp2.nMediaTypes * sizeof(REGPINTYPES)); if (!pTypes) { IFilterMapper2_Release(pMapper); return E_OUTOFMEMORY; } /* FIXME: Native devenum seems to register a lot more types for * DSound than we do. Not sure what purpose they serve */ pTypes[0].clsMajorType = &MEDIATYPE_Audio; pTypes[0].clsMinorType = &MEDIASUBTYPE_PCM; rfp2.lpMediaType = pTypes; res = IFilterMapper2_RegisterFilter(pMapper, &CLSID_AudioRender, wocaps.szPname, &pMoniker, &CLSID_AudioRendererCategory, wocaps.szPname, &rf2); /* FIXME: do additional stuff with IMoniker here, depending on what RegisterFilter does */ if (pMoniker) { IMoniker_Release(pMoniker); pMoniker = NULL; } wsprintfW(szDSoundName, szDSoundNameFormat, wocaps.szPname); res = IFilterMapper2_RegisterFilter(pMapper, &CLSID_DSoundRender, szDSoundName, &pMoniker, &CLSID_AudioRendererCategory, szDSoundName, &rf2); /* FIXME: do additional stuff with IMoniker here, depending on what RegisterFilter does */ if (pMoniker) IMoniker_Release(pMoniker); if (i == iDefaultDevice) { FIXME("Default device\n"); } CoTaskMemFree(pTypes); } } numDevs = waveInGetNumDevs(); res = DEVENUM_CreateAMCategoryKey(&CLSID_AudioInputDeviceCategory); if (FAILED(res)) /* can't register any devices in this category */ numDevs = 0; rfp2.dwFlags = REG_PINFLAG_B_OUTPUT; for (i = 0; i < numDevs; i++) { if (waveInGetDevCapsW(i, &wicaps, sizeof(WAVEINCAPSW)) == MMSYSERR_NOERROR) { IMoniker * pMoniker = NULL; rfp2.nMediaTypes = 1; pTypes = CoTaskMemAlloc(rfp2.nMediaTypes * sizeof(REGPINTYPES)); if (!pTypes) { IFilterMapper2_Release(pMapper); return E_OUTOFMEMORY; } /* FIXME: Not sure if these are correct */ pTypes[0].clsMajorType = &MEDIATYPE_Audio; pTypes[0].clsMinorType = &MEDIASUBTYPE_PCM; rfp2.lpMediaType = pTypes; res = IFilterMapper2_RegisterFilter(pMapper, &CLSID_AudioRecord, wicaps.szPname, &pMoniker, &CLSID_AudioInputDeviceCategory, wicaps.szPname, &rf2); /* FIXME: do additional stuff with IMoniker here, depending on what RegisterFilter does */ if (pMoniker) IMoniker_Release(pMoniker); CoTaskMemFree(pTypes); } } numDevs = midiOutGetNumDevs(); res = DEVENUM_CreateAMCategoryKey(&CLSID_MidiRendererCategory); if (FAILED(res)) /* can't register any devices in this category */ numDevs = 0; rfp2.dwFlags = REG_PINFLAG_B_RENDERER; for (i = 0; i < numDevs; i++) { if (midiOutGetDevCapsW(i, &mocaps, sizeof(MIDIOUTCAPSW)) == MMSYSERR_NOERROR) { IMoniker * pMoniker = NULL; rfp2.nMediaTypes = 1; pTypes = CoTaskMemAlloc(rfp2.nMediaTypes * sizeof(REGPINTYPES)); if (!pTypes) { IFilterMapper2_Release(pMapper); return E_OUTOFMEMORY; } /* FIXME: Not sure if these are correct */ pTypes[0].clsMajorType = &MEDIATYPE_Midi; pTypes[0].clsMinorType = &MEDIASUBTYPE_None; rfp2.lpMediaType = pTypes; res = IFilterMapper2_RegisterFilter(pMapper, &CLSID_AVIMIDIRender, mocaps.szPname, &pMoniker, &CLSID_MidiRendererCategory, mocaps.szPname, &rf2); /* FIXME: do additional stuff with IMoniker here, depending on what RegisterFilter does */ /* Native version sets MidiOutId */ if (pMoniker) IMoniker_Release(pMoniker); if (i == iDefaultDevice) { FIXME("Default device\n"); } CoTaskMemFree(pTypes); } } res = DEVENUM_CreateAMCategoryKey(&CLSID_VideoInputDeviceCategory); if (SUCCEEDED(res)) for (i = 0; i < 10; i++) { WCHAR szDeviceName[32], szDeviceVersion[32], szDevicePath[10]; if (capGetDriverDescriptionW ((WORD) i, szDeviceName, sizeof(szDeviceName)/sizeof(WCHAR), szDeviceVersion, sizeof(szDeviceVersion)/sizeof(WCHAR))) { IMoniker * pMoniker = NULL; IPropertyBag * pPropBag = NULL; WCHAR dprintf[] = { 'v','i','d','e','o','%','d',0 }; snprintfW(szDevicePath, sizeof(szDevicePath)/sizeof(WCHAR), dprintf, i); /* The above code prevents 1 device with a different ID overwriting another */ rfp2.nMediaTypes = 1; pTypes = CoTaskMemAlloc(rfp2.nMediaTypes * sizeof(REGPINTYPES)); if (!pTypes) { IFilterMapper2_Release(pMapper); return E_OUTOFMEMORY; } pTypes[0].clsMajorType = &MEDIATYPE_Video; pTypes[0].clsMinorType = &MEDIASUBTYPE_None; rfp2.lpMediaType = pTypes; res = IFilterMapper2_RegisterFilter(pMapper, &CLSID_VfwCapture, szDeviceName, &pMoniker, &CLSID_VideoInputDeviceCategory, szDevicePath, &rf2); if (pMoniker) { OLECHAR wszVfwIndex[] = { 'V','F','W','I','n','d','e','x',0 }; VARIANT var; V_VT(&var) = VT_I4; V_UNION(&var, ulVal) = i; res = IMoniker_BindToStorage(pMoniker, NULL, NULL, &IID_IPropertyBag, (LPVOID)&pPropBag); if (SUCCEEDED(res)) res = IPropertyBag_Write(pPropBag, wszVfwIndex, &var); IMoniker_Release(pMoniker); } if (i == iDefaultDevice) FIXME("Default device\n"); CoTaskMemFree(pTypes); } } } if (pMapper) IFilterMapper2_Release(pMapper); SetEvent(DEVENUM_populate_handle); return res; }
static HRESULT do_process_key(LPCOLESTR *pstr, HKEY parent_key, strbuf *buf, BOOL do_register) { LPCOLESTR iter = *pstr; HRESULT hres; LONG lres; HKEY hkey = 0; strbuf name; enum { NORMAL, NO_REMOVE, IS_VAL, FORCE_REMOVE, DO_DELETE } key_type = NORMAL; static const WCHAR wstrNoRemove[] = {'N','o','R','e','m','o','v','e',0}; static const WCHAR wstrForceRemove[] = {'F','o','r','c','e','R','e','m','o','v','e',0}; static const WCHAR wstrDelete[] = {'D','e','l','e','t','e',0}; static const WCHAR wstrval[] = {'v','a','l',0}; iter = *pstr; hres = get_word(&iter, buf); if(FAILED(hres)) return hres; strbuf_init(&name); while(buf->str[1] || buf->str[0] != '}') { key_type = NORMAL; if(!lstrcmpiW(buf->str, wstrNoRemove)) key_type = NO_REMOVE; else if(!lstrcmpiW(buf->str, wstrForceRemove)) key_type = FORCE_REMOVE; else if(!lstrcmpiW(buf->str, wstrval)) key_type = IS_VAL; else if(!lstrcmpiW(buf->str, wstrDelete)) key_type = DO_DELETE; if(key_type != NORMAL) { hres = get_word(&iter, buf); if(FAILED(hres)) break; } TRACE("name = %s\n", debugstr_w(buf->str)); if(do_register) { if(key_type == IS_VAL) { hkey = parent_key; strbuf_write(buf->str, &name, -1); }else if(key_type == DO_DELETE) { TRACE("Deleting %s\n", debugstr_w(buf->str)); lres = RegDeleteTreeW(parent_key, buf->str); }else { if(key_type == FORCE_REMOVE) RegDeleteTreeW(parent_key, buf->str); lres = RegCreateKeyW(parent_key, buf->str, &hkey); if(lres != ERROR_SUCCESS) { WARN("Could not create(open) key: %08x\n", lres); hres = HRESULT_FROM_WIN32(lres); break; } } }else if(key_type != IS_VAL && key_type != DO_DELETE) { strbuf_write(buf->str, &name, -1); lres = RegOpenKeyW(parent_key, buf->str, &hkey); if(lres != ERROR_SUCCESS) WARN("Could not open key %s: %08x\n", debugstr_w(name.str), lres); } if(key_type != DO_DELETE && *iter == '=') { iter++; hres = get_word(&iter, buf); if(FAILED(hres)) break; if(buf->len != 1) { WARN("Wrong registry type: %s\n", debugstr_w(buf->str)); hres = DISP_E_EXCEPTION; break; } if(do_register) { switch(buf->str[0]) { case 's': hres = get_word(&iter, buf); if(FAILED(hres)) break; lres = RegSetValueExW(hkey, name.len ? name.str : NULL, 0, REG_SZ, (PBYTE)buf->str, (lstrlenW(buf->str)+1)*sizeof(WCHAR)); if(lres != ERROR_SUCCESS) { WARN("Could set value of key: %08x\n", lres); hres = HRESULT_FROM_WIN32(lres); break; } break; case 'd': { WCHAR *end; DWORD dw; if(*iter == '0' && iter[1] == 'x') { iter += 2; dw = strtolW(iter, &end, 16); }else { dw = strtolW(iter, &end, 10); } iter = end; lres = RegSetValueExW(hkey, name.len ? name.str : NULL, 0, REG_DWORD, (PBYTE)&dw, sizeof(dw)); if(lres != ERROR_SUCCESS) { WARN("Could set value of key: %08x\n", lres); hres = HRESULT_FROM_WIN32(lres); break; } break; } default: WARN("Wrong resource type: %s\n", debugstr_w(buf->str)); hres = DISP_E_EXCEPTION; }; if(FAILED(hres)) break; }else { if(*iter == '-') iter++; hres = get_word(&iter, buf); if(FAILED(hres)) break; } }else if(key_type == IS_VAL) { WARN("value not set!\n"); hres = DISP_E_EXCEPTION; break; } if(key_type != IS_VAL && key_type != DO_DELETE && *iter == '{' && isspaceW(iter[1])) { hres = get_word(&iter, buf); if(FAILED(hres)) break; hres = do_process_key(&iter, hkey, buf, do_register); if(FAILED(hres)) break; } TRACE("%x %x\n", do_register, key_type); if(!do_register && (key_type == NORMAL || key_type == FORCE_REMOVE)) { TRACE("Deleting %s\n", debugstr_w(name.str)); RegDeleteKeyW(parent_key, name.str); } if(hkey && key_type != IS_VAL) RegCloseKey(hkey); hkey = 0; name.len = 0; hres = get_word(&iter, buf); if(FAILED(hres)) break; } HeapFree(GetProcessHeap(), 0, name.str); if(hkey && key_type != IS_VAL) RegCloseKey(hkey); *pstr = iter; return hres; }
static int reg_delete(WCHAR *key_name, WCHAR *value_name, BOOL value_empty, BOOL value_all, BOOL force) { LPWSTR p; HKEY root,subkey; static const WCHAR stubW[] = {'D','E','L','E','T','E', ' ','-',' ','%','s',' ','%','s',' ','%','d',' ','%','d',' ','%','d','\n' ,0 }; reg_printfW(stubW, key_name, value_name, value_empty, value_all, force); if (key_name[0]=='\\' && key_name[1]=='\\') { reg_message(STRING_NO_REMOTE); return 1; } p = strchrW(key_name,'\\'); if (!p) { reg_message(STRING_INVALID_KEY); return 1; } p++; root = get_rootkey(key_name); if (!root) { reg_message(STRING_INVALID_KEY); return 1; } if (value_name && value_empty) { reg_message(STRING_INVALID_CMDLINE); return 1; } if (value_empty && value_all) { reg_message(STRING_INVALID_CMDLINE); return 1; } if (!force) { /* FIXME: Prompt for delete */ } /* Delete subtree only if no /v* option is given */ if (!value_name && !value_empty && !value_all) { if (RegDeleteTreeW(root,p)!=ERROR_SUCCESS) { reg_message(STRING_CANNOT_FIND); return 1; } reg_message(STRING_SUCCESS); return 0; } if(RegOpenKeyW(root,p,&subkey)!=ERROR_SUCCESS) { reg_message(STRING_CANNOT_FIND); return 1; } if (value_all) { LPWSTR szValue; DWORD maxValue; DWORD count; LONG rc; rc = RegQueryInfoKeyW(subkey, NULL, NULL, NULL, NULL, NULL, NULL, NULL, &maxValue, NULL, NULL, NULL); if (rc != ERROR_SUCCESS) { /* FIXME: failure */ RegCloseKey(subkey); return 1; } maxValue++; szValue = HeapAlloc(GetProcessHeap(),0,maxValue*sizeof(WCHAR)); while (1) { count = maxValue; rc = RegEnumValueW(subkey, 0, szValue, &count, NULL, NULL, NULL, NULL); if (rc == ERROR_SUCCESS) { rc = RegDeleteValueW(subkey, szValue); if (rc != ERROR_SUCCESS) break; } else break; } if (rc != ERROR_SUCCESS) { /* FIXME delete failed */ } } else if (value_name) { if (RegDeleteValueW(subkey,value_name) != ERROR_SUCCESS) { RegCloseKey(subkey); reg_message(STRING_CANNOT_FIND); return 1; } } else if (value_empty) { RegSetValueExW(subkey,NULL,0,REG_SZ,NULL,0); } RegCloseKey(subkey); reg_message(STRING_SUCCESS); return 0; }
STDAPI DllUnregisterServer() { std::wstring strClsid = L"CLSID\\" + GetFsBoxCLSID(); LSTATUS res = RegDeleteTreeW(HKEY_CLASSES_ROOT, strClsid.c_str()); return (ERROR_SUCCESS == res) ? S_OK : E_FAIL;; }
NTSTATUS FspNpUnregister(VOID) { WCHAR RegBuffer[1024]; PWSTR P, Part; DWORD RegResult, RegType, RegBufferSize; HKEY RegKey; BOOLEAN FoundProvider; RegResult = RegOpenKeyExW( HKEY_LOCAL_MACHINE, L"SYSTEM\\CurrentControlSet\\Control\\NetworkProvider\\Order", 0, KEY_ALL_ACCESS, &RegKey); if (ERROR_SUCCESS != RegResult) return FspNtStatusFromWin32(RegResult); RegBufferSize = sizeof RegBuffer - sizeof L"," FSP_NP_NAME; RegResult = RegQueryValueExW(RegKey, L"ProviderOrder", 0, &RegType, (PVOID)RegBuffer, &RegBufferSize); if (ERROR_SUCCESS != RegResult) goto close_and_exit; RegBufferSize /= sizeof(WCHAR); FoundProvider = FALSE; RegBuffer[RegBufferSize] = L'\0'; P = RegBuffer, Part = P; do { if (L',' == *P || '\0' == *P) { if (CSTR_EQUAL == CompareStringW(LOCALE_INVARIANT, NORM_IGNORECASE, Part, (int)(P - Part), L"" FSP_NP_NAME, (int)(sizeof L"" FSP_NP_NAME - sizeof(WCHAR)) / sizeof(WCHAR))) { FoundProvider = TRUE; break; } else Part = P + 1; } } while (L'\0' != *P++); if (FoundProvider) { if (L',' == *P) P++; RtlMoveMemory(Part, P, (lstrlenW(P) + 1) * sizeof(WCHAR)); RegBufferSize = lstrlenW(RegBuffer); while (0 < RegBufferSize && ',' == RegBuffer[RegBufferSize - 1]) RegBufferSize--; RegBuffer[RegBufferSize] = L'\0'; RegBufferSize++; RegResult = RegSetValueExW(RegKey, L"ProviderOrder", 0, REG_SZ, (PVOID)RegBuffer, RegBufferSize * sizeof(WCHAR)); if (ERROR_SUCCESS != RegResult) goto close_and_exit; } RegCloseKey(RegKey); RegResult = RegDeleteTreeW( HKEY_LOCAL_MACHINE, L"SYSTEM\\CurrentControlSet\\Services\\" FSP_NP_NAME); if (ERROR_SUCCESS != RegResult && ERROR_FILE_NOT_FOUND != RegResult) return FspNtStatusFromWin32(RegResult); return STATUS_SUCCESS; close_and_exit: RegCloseKey(RegKey); return FspNtStatusFromWin32(RegResult); }
static int reg_delete(WCHAR *key_name, WCHAR *value_name, BOOL value_empty, BOOL value_all, BOOL force) { LPWSTR p; HKEY root,subkey; if (!sane_path(key_name)) return 1; p = strchrW(key_name,'\\'); if (!p) { output_message(STRING_INVALID_KEY); return 1; } p++; root = path_get_rootkey(key_name); if (!root) { output_message(STRING_INVALID_KEY); return 1; } if ((value_name && value_empty) || (value_name && value_all) || (value_empty && value_all)) { output_message(STRING_INVALID_CMDLINE); return 1; } if (!force) { BOOL ret; if (value_name || value_empty) ret = ask_confirm(STRING_DELETE_VALUE, value_name); else if (value_all) ret = ask_confirm(STRING_DELETE_VALUEALL, key_name); else ret = ask_confirm(STRING_DELETE_SUBKEY, key_name); if (!ret) { output_message(STRING_CANCELLED); return 0; } } /* Delete subtree only if no /v* option is given */ if (!value_name && !value_empty && !value_all) { if (RegDeleteTreeW(root,p)!=ERROR_SUCCESS) { output_message(STRING_CANNOT_FIND); return 1; } output_message(STRING_SUCCESS); return 0; } if(RegOpenKeyW(root,p,&subkey)!=ERROR_SUCCESS) { output_message(STRING_CANNOT_FIND); return 1; } if (value_all) { LPWSTR szValue; DWORD maxValue; DWORD count; LONG rc; rc = RegQueryInfoKeyW(subkey, NULL, NULL, NULL, NULL, NULL, NULL, NULL, &maxValue, NULL, NULL, NULL); if (rc != ERROR_SUCCESS) { /* FIXME: failure */ RegCloseKey(subkey); return 1; } maxValue++; szValue = HeapAlloc(GetProcessHeap(),0,maxValue*sizeof(WCHAR)); while (1) { count = maxValue; rc = RegEnumValueW(subkey, 0, szValue, &count, NULL, NULL, NULL, NULL); if (rc == ERROR_SUCCESS) { rc = RegDeleteValueW(subkey, szValue); if (rc != ERROR_SUCCESS) break; } else break; } if (rc != ERROR_SUCCESS) { /* FIXME delete failed */ } } else if (value_name) { if (RegDeleteValueW(subkey,value_name) != ERROR_SUCCESS) { RegCloseKey(subkey); output_message(STRING_CANNOT_FIND); return 1; } } else if (value_empty) { RegSetValueExW(subkey,NULL,0,REG_SZ,NULL,0); } RegCloseKey(subkey); output_message(STRING_SUCCESS); return 0; }
int main(int argc, char *argv[]) { DWORD dwError; HANDLE hReg = NULL; PLWREG_VALUE_ATTRIBUTES pAttr = NULL; PLWREG_VALUE_ATTRIBUTES pAttr_int = NULL; PWSTR* ppwszRootKeyNames = NULL; DWORD dwNumRootKeys = 0; wchar16_t szSubKey[] = {'a', 0}; wchar16_t szSubKey1[] = {'b', 0}; wchar16_t szValueName[] = {'a','t','t','r',0}; wchar16_t szValueName1[] = {'a','t','t','r','1',0}; HKEY hKey = NULL; HKEY hSubKey = NULL; HKEY hSubSubKey = NULL; PLWREG_CURRENT_VALUEINFO pCurrentValue = NULL; PLWREG_VALUE_ATTRIBUTES pValueAttributes = NULL; PLWREG_VALUE_ATTRIBUTES pValueAttributes_int = NULL; ValueAttribute.Range.ppszRangeEnumStrings = ppszRangeEnumStrings; ValueAttribute_int.Range.RangeInteger.Max = 100; ValueAttribute_int.Range.RangeInteger.Min = 1; DWORD dwType = REG_NONE; PBYTE pData[MAX_VALUE_LENGTH] = {0}; DWORD cbData = MAX_VALUE_LENGTH; wchar16_t pCurrData[] = {'C', 'u', 'r', 'r', 'e', 'n', 't', 0}; dwError = RegConvertValueAttributesAToW(ValueAttribute, &pAttr); BAIL_ON_REG_ERROR(dwError); dwError = RegConvertValueAttributesAToW(ValueAttribute_int, &pAttr_int); BAIL_ON_REG_ERROR(dwError); dwError = RegOpenServer(&hReg); BAIL_ON_REG_ERROR(dwError); dwError = RegEnumRootKeysW(hReg, &ppwszRootKeyNames, &dwNumRootKeys); BAIL_ON_REG_ERROR(dwError); dwError = RegOpenKeyExW( hReg, NULL, ppwszRootKeyNames[0], 0, KEY_ALL_ACCESS | KEY_SET_VALUE | KEY_CREATE_SUB_KEY | DELETE, &hKey); BAIL_ON_REG_ERROR(dwError); dwError = RegCreateKeyExW( hReg, hKey, szSubKey, 0, NULL, 0, KEY_ALL_ACCESS, NULL, &hSubKey, NULL); BAIL_ON_REG_ERROR(dwError); dwError = RegCreateKeyExW( hReg, hSubKey, szSubKey1, 0, NULL, 0, KEY_ALL_ACCESS, NULL, &hSubSubKey, NULL); BAIL_ON_REG_ERROR(dwError); dwError = RegSetValueAttributesW( hReg, hKey, NULL, szValueName, pAttr); BAIL_ON_REG_ERROR(dwError); dwError = RegSetValueAttributesW( hReg, hKey, NULL, szValueName1, pAttr_int); BAIL_ON_REG_ERROR(dwError); dwError = RegSetValueAttributesW( hReg, hKey, szSubKey, szValueName, pAttr); BAIL_ON_REG_ERROR(dwError); dwError = RegSetValueAttributesW( hReg, hKey, szSubKey, szValueName1, pAttr); BAIL_ON_REG_ERROR(dwError); dwError = RegSetValueAttributesW( hReg, hSubSubKey, NULL, szValueName1, pAttr_int); BAIL_ON_REG_ERROR(dwError); dwError = RegSetValueAttributesW( hReg, hSubSubKey, NULL, szValueName, pAttr); BAIL_ON_REG_ERROR(dwError); dwError = RegGetValueAttributesW( hReg, hKey, NULL, szValueName, &pCurrentValue, &pValueAttributes); BAIL_ON_REG_ERROR(dwError); dwError = RegGetValueAttributesW( hReg, hKey, NULL, szValueName1, NULL, &pValueAttributes_int); BAIL_ON_REG_ERROR(dwError); dwError = RegSetValueExW( hReg, hSubKey, szValueName, 0, REG_SZ, (const BYTE*)pCurrData, (wc16slen(pCurrData)+1)*sizeof(*pCurrData)); BAIL_ON_REG_ERROR(dwError); dwError = RegGetValueW( hReg, hKey, szSubKey, szValueName, RRF_RT_REG_NONE, &dwType, pData, &cbData); BAIL_ON_REG_ERROR(dwError); dwError = RegDeleteValueAttributesW( hReg, hKey, NULL, szValueName); BAIL_ON_REG_ERROR(dwError); dwError = RegDeleteTreeW( hReg, hKey, szSubKey); if (LWREG_ERROR_KEY_IS_ACTIVE == dwError) { if (hSubKey) { RegCloseKey(hReg, hSubKey); } if (hSubSubKey) { RegCloseKey(hReg, hSubSubKey); } dwError = RegDeleteTreeW( hReg, hKey, szSubKey); BAIL_ON_REG_ERROR(dwError); } BAIL_ON_REG_ERROR(dwError); cleanup: if (hKey) { RegCloseKey(hReg, hKey); } if (hSubKey) { RegCloseKey(hReg, hSubKey); } if (hSubSubKey) { RegCloseKey(hReg, hSubSubKey); } if (hReg) { RegCloseServer(hReg); } RegFreeWC16StringArray(ppwszRootKeyNames, dwNumRootKeys); RegSafeFreeValueAttributes(&pAttr); RegSafeFreeCurrentValueInfo(&pCurrentValue); RegSafeFreeValueAttributes(&pValueAttributes); return dwError; error: goto cleanup; }
HRESULT WINAPI CRecycleBinDeskBand::UpdateRegistry(_In_ BOOL bRegister) { LOG("UpdateRegistry()"); LOG2(" bRegister", bRegister); HRESULT hr = S_OK; if (bRegister) { WCHAR szCLSID[MAX_PATH]; StringFromGUID2(CLSID_RecycleBinDeskBand, szCLSID, ARRAYSIZE(szCLSID)); WCHAR szSubkey[MAX_PATH]; HKEY hKey; hr = StringCchPrintfW(szSubkey, ARRAYSIZE(szSubkey), L"CLSID\\%s", szCLSID); if (SUCCEEDED(hr)) { hr = E_FAIL; if (ERROR_SUCCESS == RegCreateKeyExW(HKEY_CLASSES_ROOT, szSubkey, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, &hKey, NULL)) { WCHAR const szName[] = L"Recyclebin"; // TODO: externalize //WCHAR szName[MAX_PATH]; //ExtractRecycleBinName(szName, ARRAYSIZE(szName)); if (ERROR_SUCCESS == RegSetValueExW(hKey, NULL, 0, REG_SZ, (LPBYTE)szName, sizeof(szName))) { hr = S_OK; } RegCloseKey(hKey); } } if (SUCCEEDED(hr)) { hr = StringCchPrintfW(szSubkey, ARRAYSIZE(szSubkey), L"CLSID\\%s\\InprocServer32", szCLSID); if (SUCCEEDED(hr)) { hr = HRESULT_FROM_WIN32(RegCreateKeyExW(HKEY_CLASSES_ROOT, szSubkey, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, &hKey, NULL)); if (SUCCEEDED(hr)) { WCHAR szModule[MAX_PATH]; if (GetModuleFileNameW(g_hInst, szModule, ARRAYSIZE(szModule))) { DWORD cch = lstrlen(szModule); hr = HRESULT_FROM_WIN32(RegSetValueExW(hKey, NULL, 0, REG_SZ, (LPBYTE)szModule, cch * sizeof(szModule[0]))); } if (SUCCEEDED(hr)) { WCHAR const szModel[] = L"Apartment"; hr = HRESULT_FROM_WIN32(RegSetValueExW(hKey, L"ThreadingModel", 0, REG_SZ, (LPBYTE)szModel, sizeof(szModel))); } RegCloseKey(hKey); } } } } else { WCHAR szCLSID[MAX_PATH]; StringFromGUID2(CLSID_RecycleBinDeskBand, szCLSID, ARRAYSIZE(szCLSID)); WCHAR szSubkey[MAX_PATH]; HRESULT hr = StringCchPrintfW(szSubkey, ARRAYSIZE(szSubkey), L"CLSID\\%s", szCLSID); if (SUCCEEDED(hr)) { if (ERROR_SUCCESS != RegDeleteTreeW(HKEY_CLASSES_ROOT, szSubkey)) { hr = E_FAIL; } } return SUCCEEDED(hr) ? S_OK : SELFREG_E_CLASS; } LOG2(" hr", hr); return hr; }