QString getDevicesXmlPath() { // Note that the following call will return a null string on platforms other // than Windows. If support is required on other platforms for devices.xml, // an alternative mechanism for retrieving the location of this file will // be required. return readRegistryKey(SYMBIAN_SDKS_REG_HANDLE, SYMBIAN_SDKS_REG_SUBKEY); }
SEXP readRegistry(SEXP call, SEXP op, SEXP args, SEXP env) { SEXP ans; HKEY hive, hkey; LONG res; const wchar_t *key; int maxdepth, view; REGSAM acc = KEY_READ; args = CDR(args); if(!isString(CAR(args)) || LENGTH(CAR(args)) != 1) error(_("invalid '%s' value"), "key"); key = filenameToWchar(STRING_ELT(CAR(args), 0), 0); if(!isString(CADR(args)) || LENGTH(CADR(args)) != 1) error(_("invalid '%s' value"), "hive"); maxdepth = asInteger(CADDR(args)); if(maxdepth == NA_INTEGER || maxdepth < 1) error(_("invalid '%s' value"), "maxdepth"); hive = find_hive(CHAR(STRING_ELT(CADR(args), 0))); view = asInteger(CADDDR(args)); /* Or KEY_READ with KEY_WOW64_64KEY or KEY_WOW64_32KEY to explicitly access the 64- or 32- bit registry view. See http://msdn.microsoft.com/en-us/library/aa384129(VS.85).aspx */ if(view == 2) acc |= KEY_WOW64_32KEY; else if(view == 3) acc |= KEY_WOW64_64KEY; res = RegOpenKeyExW(hive, key, 0, acc, &hkey); if (res == ERROR_FILE_NOT_FOUND) error(_("Registry key '%ls' not found"), key); if (res != ERROR_SUCCESS) error("RegOpenKeyEx error code %d: '%s'", (int) res, formatError(res)); ans = readRegistryKey(hkey, maxdepth, view); RegCloseKey(hkey); return ans; }
static SEXP readRegistryKey(HKEY hkey, int depth, int view) { int i, k = 0, size0, *indx; SEXP ans, nm, ans0, nm0, tmp, sind; DWORD res, nsubkeys, maxsubkeylen, nval, maxvalnamlen, size; wchar_t *name; HKEY sub; REGSAM acc = KEY_READ; if (depth <= 0) return mkString("<subkey>"); if(view == 2) acc |= KEY_WOW64_32KEY; else if(view == 3) acc |= KEY_WOW64_64KEY; res = RegQueryInfoKey(hkey, NULL, NULL, NULL, &nsubkeys, &maxsubkeylen, NULL, &nval, &maxvalnamlen, NULL, NULL, NULL); if (res != ERROR_SUCCESS) error("RegQueryInfoKey error code %d: '%s'", (int) res, formatError(res)); size0 = max(maxsubkeylen, maxvalnamlen) + 1; name = (wchar_t *) R_alloc(size0, sizeof(wchar_t)); PROTECT(ans = allocVector(VECSXP, nval + nsubkeys)); PROTECT(nm = allocVector(STRSXP, nval+ nsubkeys)); if (nval > 0) { PROTECT(ans0 = allocVector(VECSXP, nval)); PROTECT(nm0 = allocVector(STRSXP, nval)); for (i = 0; i < nval; i++) { size = size0; res = RegEnumValueW(hkey, i, (LPWSTR) name, &size, NULL, NULL, NULL, NULL); if (res != ERROR_SUCCESS) break; SET_VECTOR_ELT(ans0, i, readRegistryKey1(hkey, name)); SET_STRING_ELT(nm0, i, mkCharUcs(name)); } /* now sort by name */ PROTECT(sind = allocVector(INTSXP, nval)); indx = INTEGER(sind); for (i = 0; i < nval; i++) indx[i] = i; orderVector1(indx, nval, nm0, TRUE, FALSE, R_NilValue); for (i = 0; i < nval; i++, k++) { SET_VECTOR_ELT(ans, k, VECTOR_ELT(ans0, indx[i])); if (LENGTH(tmp = STRING_ELT(nm0, indx[i]))) SET_STRING_ELT(nm, k, tmp); else SET_STRING_ELT(nm, k, mkChar("(Default)")); } UNPROTECT(3); } if (nsubkeys > 0) { PROTECT(ans0 = allocVector(VECSXP, nsubkeys)); PROTECT(nm0 = allocVector(STRSXP, nsubkeys)); for (i = 0; i < nsubkeys; i++) { size = size0; res = RegEnumKeyExW(hkey, i, (LPWSTR) name, &size, NULL, NULL, NULL, NULL); if (res != ERROR_SUCCESS) break; res = RegOpenKeyExW(hkey, (LPWSTR) name, 0, acc, &sub); if (res != ERROR_SUCCESS) break; SET_VECTOR_ELT(ans0, i, readRegistryKey(sub, depth-1, view)); SET_STRING_ELT(nm0, i, mkCharUcs(name)); RegCloseKey(sub); } /* now sort by name */ PROTECT(sind = allocVector(INTSXP, nsubkeys)); indx = INTEGER(sind); for (i = 0; i < nsubkeys; i++) indx[i] = i; orderVector1(indx, nsubkeys, nm0, TRUE, FALSE, R_NilValue); for (i = 0; i < nsubkeys; i++, k++) { SET_VECTOR_ELT(ans, k, VECTOR_ELT(ans0, indx[i])); SET_STRING_ELT(nm, k, STRING_ELT(nm0, indx[i])); } UNPROTECT(3); } setAttrib(ans, R_NamesSymbol, nm); UNPROTECT(2); return ans; }