static BOOL sane_path(const WCHAR *key) { unsigned int i = strlenW(key); if (i < 3 || (key[i - 1] == '\\' && key[i - 2] == '\\')) { reg_message(STRING_INVALID_KEY); return FALSE; } if (key[0] == '\\' && key[1] == '\\' && key[2] != '\\') { reg_message(STRING_NO_REMOTE); return FALSE; } return TRUE; }
int wmain(int argc, WCHAR *argvW[]) { int i; static const WCHAR addW[] = {'a','d','d',0}; static const WCHAR deleteW[] = {'d','e','l','e','t','e',0}; static const WCHAR queryW[] = {'q','u','e','r','y',0}; static const WCHAR slashDW[] = {'/','d',0}; static const WCHAR slashFW[] = {'/','f',0}; static const WCHAR slashHW[] = {'/','h',0}; static const WCHAR slashSW[] = {'/','s',0}; static const WCHAR slashTW[] = {'/','t',0}; static const WCHAR slashVW[] = {'/','v',0}; static const WCHAR slashVAW[] = {'/','v','a',0}; static const WCHAR slashVEW[] = {'/','v','e',0}; static const WCHAR slashHelpW[] = {'/','?',0}; if (argc < 2 || !lstrcmpW(argvW[1], slashHelpW) || !lstrcmpiW(argvW[1], slashHW)) { reg_message(STRING_USAGE); return 0; } if (!lstrcmpiW(argvW[1], addW)) { WCHAR *key_name, *value_name = NULL, *type = NULL, separator = '\0', *data = NULL; BOOL value_empty = FALSE, force = FALSE; if (argc < 3) { reg_message(STRING_INVALID_CMDLINE); return 1; } else if (argc == 3 && (!lstrcmpW(argvW[2], slashHelpW) || !lstrcmpiW(argvW[2], slashHW))) { reg_message(STRING_ADD_USAGE); return 0; } key_name = argvW[2]; for (i = 1; i < argc; i++) { if (!lstrcmpiW(argvW[i], slashVW)) value_name = argvW[++i]; else if (!lstrcmpiW(argvW[i], slashVEW)) value_empty = TRUE; else if (!lstrcmpiW(argvW[i], slashTW)) type = argvW[++i]; else if (!lstrcmpiW(argvW[i], slashSW)) separator = argvW[++i][0]; else if (!lstrcmpiW(argvW[i], slashDW)) data = argvW[++i]; else if (!lstrcmpiW(argvW[i], slashFW)) force = TRUE; } return reg_add(key_name, value_name, value_empty, type, separator, data, force); } else if (!lstrcmpiW(argvW[1], deleteW)) { WCHAR *key_name, *value_name = NULL; BOOL value_empty = FALSE, value_all = FALSE, force = FALSE; if (argc < 3) { reg_message(STRING_INVALID_CMDLINE); return 1; } else if (argc == 3 && (!lstrcmpW(argvW[2], slashHelpW) || !lstrcmpiW(argvW[2], slashHW))) { reg_message(STRING_DELETE_USAGE); return 0; } key_name = argvW[2]; for (i = 1; i < argc; i++) { if (!lstrcmpiW(argvW[i], slashVW)) value_name = argvW[++i]; else if (!lstrcmpiW(argvW[i], slashVEW)) value_empty = TRUE; else if (!lstrcmpiW(argvW[i], slashVAW)) value_all = TRUE; else if (!lstrcmpiW(argvW[i], slashFW)) force = TRUE; } return reg_delete(key_name, value_name, value_empty, value_all, force); } else if (!lstrcmpiW(argvW[1], queryW)) { WCHAR *key_name, *value_name = NULL; BOOL value_empty = FALSE, subkey = FALSE; if (argc < 3) { reg_message(STRING_INVALID_CMDLINE); return 1; } else if (argc == 3 && (!lstrcmpW(argvW[2], slashHelpW) || !lstrcmpiW(argvW[2], slashHW))) { reg_message(STRING_QUERY_USAGE); return 0; } key_name = argvW[2]; for (i = 1; i < argc; i++) { if (!lstrcmpiW(argvW[i], slashVW)) value_name = argvW[++i]; else if (!lstrcmpiW(argvW[i], slashVEW)) value_empty = TRUE; else if (!lstrcmpiW(argvW[i], slashSW)) subkey = TRUE; } return reg_query(key_name, value_name, value_empty, subkey); } else { reg_message(STRING_INVALID_CMDLINE); return 1; } }
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; }
static int reg_add(WCHAR *key_name, WCHAR *value_name, BOOL value_empty, WCHAR *type, WCHAR separator, WCHAR *data, BOOL force) { static const WCHAR stubW[] = {'A','D','D',' ','-',' ','%','s', ' ','%','s',' ','%','d',' ','%','s',' ','%','s',' ','%','d','\n',0 }; LPWSTR p; HKEY root,subkey; reg_printfW(stubW, key_name, value_name, value_empty, type, data, 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(RegCreateKeyW(root,p,&subkey)!=ERROR_SUCCESS) { reg_message(STRING_INVALID_KEY); return 1; } if (value_name || data) { DWORD reg_type; DWORD reg_count = 0; BYTE* reg_data = NULL; if (!force) { if (RegQueryValueW(subkey,value_name,NULL,NULL)==ERROR_SUCCESS) { /* FIXME: Prompt for overwrite */ } } reg_type = get_regtype(type); if (reg_type == -1) { RegCloseKey(subkey); reg_message(STRING_INVALID_CMDLINE); return 1; } if (data) reg_data = get_regdata(data,reg_type,separator,®_count); RegSetValueExW(subkey,value_name,0,reg_type,reg_data,reg_count); HeapFree(GetProcessHeap(),0,reg_data); } RegCloseKey(subkey); reg_message(STRING_SUCCESS); return 0; }