Exemple #1
0
static void BackupRegTree_Worker(HKEY hKey,const char *pszSubKey,struct BackupRegTreeParam *param)
{
	LONG res;
	DWORD nMaxSubKeyLen,nMaxValNameLen,nMaxValSize;
	DWORD index,cchName,dwType,cbData;
	BYTE *pData;
	char *pszName;
	register TCHAR *ptszName;
	DWORD nDbPrefixLen;
	if ((res=RegOpenKeyExA(hKey,pszSubKey,0,KEY_QUERY_VALUE|KEY_ENUMERATE_SUB_KEYS,&hKey))==ERROR_SUCCESS) {
		if ((res=RegQueryInfoKey(hKey,NULL,NULL,NULL,NULL,&nMaxSubKeyLen,NULL,NULL,&nMaxValNameLen,&nMaxValSize,NULL,NULL))==ERROR_SUCCESS) {
			if (nMaxSubKeyLen>nMaxValNameLen) nMaxValNameLen=nMaxSubKeyLen;
			/* prepare buffer */
			nDbPrefixLen=(DWORD)mir_strlen(*param->ppszDbPrefix)+mir_strlen(pszSubKey)+1;
			cchName=nDbPrefixLen+nMaxValNameLen+3;
			if (cchName>*param->pdwDbPrefixSize) {
				pszName=(char*)mir_realloc(*param->ppszDbPrefix,cchName);
				if (pszName==NULL) return;
				*param->ppszDbPrefix=pszName;
				*param->pdwDbPrefixSize=cchName;
			}
			mir_strcat(mir_strcat(*param->ppszDbPrefix,pszSubKey),"\\"); /* buffer safe */
			/* enum values */
			pszName=(char*)mir_alloc(nMaxValNameLen+1);
			if (nMaxValSize==0) nMaxValSize=1;
			pData=(BYTE*)mir_alloc(nMaxValSize);
			if (pszName!=NULL && pData!=NULL) {
				index=0;
				while(!res) {
					cchName=nMaxValNameLen+1;
					cbData=nMaxValSize;
					if ((res=RegEnumValueA(hKey,index++,pszName,&cchName,NULL,NULL,NULL,NULL))==ERROR_SUCCESS) {
						(*param->ppszDbPrefix)[nDbPrefixLen]=0;
						mir_strcat(*param->ppszDbPrefix,pszName); /* buffer safe */
						ptszName=a2t(pszName);
						if (ptszName!=NULL) {
							if (!RegQueryValueEx(hKey,ptszName,NULL,&dwType,pData,&cbData)) {

								WriteDbBackupData(*param->ppszDbPrefix,dwType,pData,cbData);

							}
							mir_free(ptszName);
						}
					}
				}
				if (res==ERROR_NO_MORE_ITEMS) res=ERROR_SUCCESS;
			}
			mir_free(pData); /* does NULL check */
			/* enum subkeys */
			if (param->level<32 && pszName!=NULL) {
				++param->level; /* can be max 32 levels deep (after prefix), restriction of RegCreateKeyEx() */
				index=0;
				while(!res) {
					cchName=nMaxSubKeyLen+1;
					if ((res=RegEnumKeyExA(hKey,index++,pszName,&cchName,NULL,NULL,NULL,NULL))==ERROR_SUCCESS) {
						(*param->ppszDbPrefix)[nDbPrefixLen]=0;
						BackupRegTree_Worker(hKey,pszName,param); /* recursion */
					}
				}
			}
			if (res==ERROR_NO_MORE_ITEMS) res=ERROR_SUCCESS;
			mir_free(pszName); /* does NULL check */
		}
		RegCloseKey(hKey);
	}
}
// Explore the registry to find a suitable version of Java.
// Returns an int which is the version of Java found (e.g. 1006 for 1.6) and the
// matching path in outJavaPath.
// Returns 0 if nothing suitable was found.
static int exploreJavaRegistry(const char *entry, REGSAM access, CPath *outJavaPath) {

    // Let's visit HKEY_LOCAL_MACHINE\SOFTWARE\JavaSoft\Java Runtime Environment [CurrentVersion]
    CPath rootKey("SOFTWARE\\JavaSoft\\");
    rootKey.addPath(entry);

    int versionInt = 0;
    CString currentVersion;
    CPath subKey(rootKey);
    if (getRegValue(subKey.cstr(), "CurrentVersion", access, &currentVersion)) {
        // CurrentVersion should be something like "1.7".
        // We want to read HKEY_LOCAL_MACHINE\SOFTWARE\JavaSoft\Java Runtime Environment\1.7 [JavaHome]
        subKey.addPath(currentVersion);
        CPath javaHome;
        if (getRegValue(subKey.cstr(), "JavaHome", access, &javaHome)) {
            versionInt = checkBinPath(&javaHome);
            if (versionInt >= 0) {
                if (gIsDebug) {
                    fprintf(stderr,
                            "Java %d found via registry: %s\n",
                            versionInt, javaHome.cstr());
                }
                *outJavaPath = javaHome;
            }
            if (versionInt >= MIN_JAVA_VERSION) {
                // Heuristic: if the current version is good enough, stop here
                return versionInt;
            }
        }
    }

    // Try again, but this time look at all the versions available
    HKEY javaHomeKey;
    LSTATUS status = RegOpenKeyExA(
        HKEY_LOCAL_MACHINE,         // hKey
        "SOFTWARE\\JavaSoft",       // lpSubKey
        0,                          // ulOptions
        KEY_READ | access,          // samDesired
        &javaHomeKey);              // phkResult
    if (status == ERROR_SUCCESS) {
        char name[256];
        DWORD index = 0;
        CPath javaHome;
        for (LONG result = ERROR_SUCCESS; result == ERROR_SUCCESS; index++) {
            DWORD nameLen = 255;
            name[nameLen] = 0;
            result = RegEnumKeyExA(
                            javaHomeKey,  // hKey
                            index,        // dwIndex
                            name,         // lpName
                            &nameLen,     // lpcName
                            NULL,         // lpReserved
                            NULL,         // lpClass
                            NULL,         // lpcClass,
                            NULL);        // lpftLastWriteTime
            if (result == ERROR_SUCCESS && nameLen < 256) {
                name[nameLen] = 0;
                CPath subKey(rootKey);
                subKey.addPath(name);

                if (getRegValue(subKey.cstr(), "JavaHome", access, &javaHome)) {
                    int v = checkBinPath(&javaHome);
                    if (v > versionInt) {
                        if (gIsDebug) {
                            fprintf(stderr,
                                    "Java %d found via registry: %s\n",
                                    versionInt, javaHome.cstr());
                        }
                        *outJavaPath = javaHome;
                        versionInt = v;
                    }
                }
            }
        }

        RegCloseKey(javaHomeKey);
    }

    return 0;
}
Exemple #3
0
int registry_walker(HKEY hkey, const char * section,  struct a6o_conf * conf){

	int ret = 0;
	HKEY hSubKey = NULL;
	char * subkey_name = NULL;
	int subkey_maxlen = 0;
	int subkey_len = 0;
	char * class = NULL;
	char * value_name = NULL;
	int value_len = 0;
	int value_maxlen = 0;
	int value_type =0;
	int data_len = 0;
	char * data_str = NULL;
	int data_int = 0;
	char ** data_list = NULL;
	char * tmp = NULL;
	int list_len = 0;
	int class_len = 0;
	int class_maxlen = 0;
	int res = 0;
	int nb_index = 0, i =0,j=0;
	int nbvalues = 0;
	struct conf_reg_data data = {0};
	

	if (hkey == NULL) {
		printf("[-] Error :: registry_walker :: invalid parameter!\n");
		return -1;
	}

	__try {


		res = RegQueryInfoKeyA(hkey, NULL, &class_len, NULL, &nb_index, &subkey_maxlen, &class_maxlen, &nbvalues, &value_maxlen, NULL,NULL,NULL);
		if (res != ERROR_SUCCESS) {
			printf("[-] Error :: RegEnumKeyExA failed! :: GLE= %d\n", res);
			ret = -3;
			__leave;
		}
		//printf("[+] Debug :: nbindex = %d :: nbvalues = %d\n",nb_index,nbvalues);
		//printf("[+] Debug :: subkey_maxlen = %d :: index = %d :: class_maxlen = %d :: nbvalues = %d\n",subkey_maxlen ,nb_index, class_maxlen, nbvalues);


		value_maxlen++;
		value_name = (char *)calloc(value_maxlen + 1, sizeof(char));

		// Get values.
		for (i = 0; i < nbvalues; i++) {

			value_len = value_maxlen;
			if ((res = RegEnumValueA(hkey, i, value_name, &value_len, NULL, &value_type, NULL, &data_len)) != ERROR_SUCCESS) {
				printf("[-] Error :: RegEnumValueA failed! :: GLE= %d\n", res);
				ret = -3;
				__leave;
			}

			// get data.
			switch (value_type) {

				case REG_DWORD:					
					if ((res = RegGetValueA(hkey,NULL,value_name,RRF_RT_ANY, NULL, &data_int,&data_len)) != ERROR_SUCCESS ) {
						printf("[-] Error :: RegEnumValueA failed! :: GLE= %d\n", res);
						break;
					}
					//printf("[+] Debug :: value_name = %s :: value_type = %d :: data_len = %d :: data_int = %d\n",value_name,value_type,data_len,data_int );
					//printf("[+] Debug :: (%s) => %d\n",value_name,data_int );

					// add value to conf struct
					if (section != NULL)
						a6o_conf_add_uint(conf, section, value_name, data_int);

					break;
				case REG_SZ:

					//printf("[+] Debug :: value_name = %s :: value_type = %d :: data_len = %d\n",value_name,value_type,data_len );					
					data_str = (char *)calloc(data_len + 1, sizeof(char));
					if ((res = RegGetValueA(hkey,NULL,value_name,RRF_RT_ANY, NULL,data_str,&data_len)) != ERROR_SUCCESS ) {
						printf("[-] Error :: RegEnumValueA failed! :: GLE= %d\n", res);
						break;
					}
					//printf("[+] Debug :: (%s) => %s\n",value_name,data_str);

					if (section != NULL)
						a6o_conf_add_string(conf, section, value_name, data_str);
					break;


				case REG_MULTI_SZ:

					//data_string
					//printf("[+] Debug :: value_name = %s :: value_type = %d :: data_len = %d\n",value_name,value_type,data_len );

					data_str = (char *)calloc(data_len + 1, sizeof(char));
					if ((res = RegGetValueA(hkey,NULL,value_name,RRF_RT_ANY, NULL,data_str,&data_len)) != ERROR_SUCCESS ) {
						printf("[-] Error :: RegEnumValueA failed! :: GLE= %d\n", res);
						break;
					}

					//printf("[+] Debug :: [%s] => %s\n",value_name,data_str);
					//printf("[+] Debug :: (%s) =>\n",value_name);

					list_len = 0;
					tmp = data_str;
					for (; *tmp != '\0'; tmp += strnlen(tmp,MAX_PATH)+1) {
						//printf("\t\tvalue = %s\n",tmp);
						list_len++;
					}
					///printf("\n");

					data_list = (char**)calloc(list_len, sizeof(char*));
					tmp = data_str;
					j = 0;
					//printf("list_len = %d\n",list_len);
					for (; *tmp != '\0'; tmp += strnlen(tmp, MAX_PATH) + 1) {
						
						data_list[j] = (char*)calloc(strnlen(tmp, MAX_PATH) + 1,sizeof(char));
						memcpy(data_list[j],tmp,strnlen(tmp, MAX_PATH) + 1);						
						//printf("\tvalue = %s\n",data_list[j]);
						
						j++;
					}
					
					if (section != NULL)
						a6o_conf_add_list(conf, section, value_name, data_list, list_len);


					if (data_list != NULL) {
						for (j = 0; j < list_len; j++) {
							free(data_list[j]);
							data_list[j] = NULL;
						}
						free(data_list);
						data_list = NULL;
					}

					if (data_str != NULL) {
						free(data_str);
						data_str = NULL;
					}

					break;

				default:
					//printf("[+] Debug :: value_name = %s :: value_type = %d :: data_len = %d\n",value_name,value_type,data_len );
					break;
				
			}

		}


		// Get subkeys
		subkey_maxlen++; // add null terminating character.
		subkey_name = (char *)calloc(subkey_maxlen + 1, sizeof(char));

		for (i = 0; i < nb_index; i++) {

			subkey_len = subkey_maxlen;
			res = RegEnumKeyExA(hkey, i, subkey_name, &subkey_len, NULL, NULL, NULL, NULL);
			if (res != ERROR_SUCCESS) {
				printf("[-] Error :: RegEnumKeyExA failed! :: GLE= %d\n", res);
				ret = -3;
				__leave;
			}

			printf("[+] Debug :: section = [%s]\n",subkey_name);
			//printf("[+] Debug :: sub_key_name = [%s] :: sub_key_len = %d :: class_len = %d\n",subkey_name, subkey_len,class_len);

			
			if ((res = RegOpenKeyA(hkey,subkey_name, &hSubKey)) != ERROR_SUCCESS) {
				printf("[-] Error :: RegOpenKeyA failed! :: GLE= %d\n", res);
				ret = -2;
				__leave;
			}


			registry_walker(hSubKey,subkey_name,conf);

			//printf("\n\n");

		}


		


		



	}
	__finally {

		if (subkey_name != NULL) {
			free(subkey_name);
			subkey_name = NULL;
		}

		if (value_name != NULL) {
			free(value_name);
			value_name = NULL;
		}

		if (hSubKey != NULL) {
			RegCloseKey(hSubKey);
			hSubKey = NULL;
		}

		if (data_str != NULL) {
			free(data_str);
			data_str = NULL;
		}

		if (data_list != NULL) {
			for (j = 0; j < list_len; j++) {
				free(data_list[j]);
				data_list[j] = NULL;
			}
			free(data_list);
			data_list = NULL;
		}


		

		

	}

	




	return ret;
}
Exemple #4
0
/* Based on RegDeleteTreeW from dlls/advapi32/registry.c */
static LSTATUS mru_RegDeleteTreeA(HKEY hKey, LPCSTR lpszSubKey)
{
    LONG ret;
    DWORD dwMaxSubkeyLen, dwMaxValueLen;
    DWORD dwMaxLen, dwSize;
    CHAR szNameBuf[MAX_PATH], *lpszName = szNameBuf;
    HKEY hSubKey = hKey;

    if(lpszSubKey)
    {
        ret = RegOpenKeyExA(hKey, lpszSubKey, 0, KEY_READ, &hSubKey);
        if (ret) return ret;
    }

    /* Get highest length for keys, values */
    ret = RegQueryInfoKeyA(hSubKey, NULL, NULL, NULL, NULL,
            &dwMaxSubkeyLen, NULL, NULL, &dwMaxValueLen, NULL, NULL, NULL);
    if (ret) goto cleanup;

    dwMaxSubkeyLen++;
    dwMaxValueLen++;
    dwMaxLen = max(dwMaxSubkeyLen, dwMaxValueLen);
    if (dwMaxLen > sizeof(szNameBuf)/sizeof(CHAR))
    {
        /* Name too big: alloc a buffer for it */
        if (!(lpszName = HeapAlloc( GetProcessHeap(), 0, dwMaxLen*sizeof(CHAR))))
        {
            ret = ERROR_NOT_ENOUGH_MEMORY;
            goto cleanup;
        }
    }


    /* Recursively delete all the subkeys */
    while (TRUE)
    {
        dwSize = dwMaxLen;
        if (RegEnumKeyExA(hSubKey, 0, lpszName, &dwSize, NULL,
                          NULL, NULL, NULL)) break;

        ret = mru_RegDeleteTreeA(hSubKey, lpszName);
        if (ret) goto cleanup;
    }

    if (lpszSubKey)
        ret = RegDeleteKeyA(hKey, lpszSubKey);
    else
        while (TRUE)
        {
            dwSize = dwMaxLen;
            if (RegEnumValueA(hKey, 0, lpszName, &dwSize,
                  NULL, NULL, NULL, NULL)) break;

            ret = RegDeleteValueA(hKey, lpszName);
            if (ret) goto cleanup;
        }

cleanup:
    /* Free buffer if allocated */
    if (lpszName != szNameBuf)
        HeapFree( GetProcessHeap(), 0, lpszName);
    if(lpszSubKey)
        RegCloseKey(hSubKey);
    return ret;
}
/////////////////////////////////////////////////////////////////////////////
// DllUnregisterServer
//
/////////////////////////////////////////////////////////////////////////////
STDAPI DllUnregisterServer(void)
{
	HKEY hRootKey = NULL;
	HKEY hModuleKey = NULL;

	HKEY hLTMKey = NULL;
	HKEY hLTMModuleKey = NULL;
	
	WCHAR* pwszCLSID = NULL;
	ULONG cBufferSize = MAX_NAME_LEN;
	GlobalModuleData* pModuleData = &g_pThisTestModule->m_gmd;
	CHAR szGuid[MAX_NAME_LEN];
	CHAR szBuffer[MAX_NAME_LEN];
	CHAR szBuffer2[MAX_NAME_LEN];
	
	//{...Guid...}
	StringFromCLSID(*pModuleData->m_pguidModuleCLSID, &pwszCLSID);
	WideCharToMultiByte(CP_ACP, 0, pwszCLSID, -1, szGuid, MAX_NAME_LEN, NULL, NULL);

	// Step 1: Remove our CLSID as an OLE Server
	//HKEY_CLASSES_ROOT\CLSID
	if(ERROR_SUCCESS == RegOpenKeyExA(HKEY_CLASSES_ROOT, "CLSID", 0, KEY_WRITE, &hRootKey))
	{
		//HKEY_CLASSES_ROOT\CLSID\{..Guid..}
		if(ERROR_SUCCESS == RegOpenKeyExA(hRootKey, szGuid, 0, KEY_WRITE, &hModuleKey))
		{
			//HKEY_CLASSES_ROOT\CLSID\{..Guid..}\InprocServer32
			RegDeleteKeyA(hModuleKey, "InprocServer32");
			RegDeleteKeyA(hModuleKey, "ProgID");
		}
		RegDeleteKeyA(hRootKey, szGuid);
		RegCloseKey(hRootKey);
	}

	//HKEY_CLASSES_ROOT\ProgID
	WideCharToMultiByte(CP_ACP, 0, pModuleData->m_wszModuleName, -1, szBuffer2, MAX_NAME_LEN, NULL, NULL);
	strcpy(szBuffer, "LTMTest.");
	strcat(szBuffer, szBuffer2);
	if(ERROR_SUCCESS == RegOpenKeyExA(HKEY_CLASSES_ROOT, szBuffer, 0, KEY_WRITE, &hRootKey))
	{
		//HKEY_CLASSES_ROOT\ProgID\CLSID
		RegDeleteKeyA(hRootKey, "CLSID");
		RegDeleteKey(hRootKey, NULL);
	}

	// Step 2: Remove LTM-specific registery entries 
	//Obtain the Key for HKEY_LOCAL_MACHINE\"SOFTWARE\Microsoft\LTM\Test Modules"
	if(ERROR_SUCCESS == RegOpenKeyExA(HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\LTM\\Test Modules", 0, KEY_WRITE, &hLTMKey))
	{
		//Obtain the Key for "...\{Guid}
		if(ERROR_SUCCESS == RegOpenKeyExA(hLTMKey, szGuid, 0, KEY_WRITE | KEY_READ, &hLTMModuleKey))
		{
			while(RegEnumKeyExA(hLTMModuleKey, 0, szBuffer, &cBufferSize, NULL, NULL, NULL, NULL) == ERROR_SUCCESS)
			{
				HKEY hLTMCase = NULL;
				if(ERROR_SUCCESS == RegOpenKeyExA(hLTMModuleKey, szBuffer, 0, KEY_WRITE | KEY_READ, &hLTMCase))
				{
					cBufferSize = MAX_NAME_LEN;
					while(RegEnumKeyExA(hLTMCase, 0, szBuffer2, &cBufferSize, NULL, NULL, NULL, NULL) == ERROR_SUCCESS)
					{
						RegDeleteKeyA(hLTMCase, szBuffer2);
						cBufferSize = MAX_NAME_LEN;
					}

					RegCloseKey(hLTMCase); hLTMCase = NULL;
					RegDeleteKeyA(hLTMModuleKey, szBuffer);
					cBufferSize = MAX_NAME_LEN;
				}
			}
			RegDeleteKeyA(hLTMKey, szGuid);
		}
	}

	RegCloseKey(hLTMKey);
	RegCloseKey(hLTMModuleKey);

	RegCloseKey(hRootKey);
	RegCloseKey(hModuleKey);
	CoTaskMemFree(pwszCLSID);
	return S_OK;
}
Exemple #6
0
std::list<ADAPTER_INFO>
KLOP_GetAdapterList()
{
	std::list<ADAPTER_INFO> RetList;
	ADAPTER_INFO	AI;	
	HKEY			hKey = NULL;
	FILETIME		ftLastWriteTime;      // last write time 
	CHAR			achKey[MAX_PATH]; 
	wchar_t			wchKey[MAX_PATH];
	ULONG			KeyLength;
	int				i;
	DWORD			retCode;

	if ( KLOP_isWinNT() )
	{
		/*
		if ( ERROR_SUCCESS == RegOpenKey( HKEY_LOCAL_MACHINE, NT_ADAPTERS_KEY, &hKey ) )
		{
			for (i = 0, retCode = ERROR_SUCCESS; retCode == ERROR_SUCCESS; i++ )
			{ 
				KeyLength = MAX_PATH;

				retCode = RegEnumKeyExW(hKey, i, wchKey, &KeyLength, NULL, NULL, NULL, &ftLastWriteTime );

				if ( ERROR_SUCCESS == retCode )
				{
					memset ( &AI , 0, sizeof ( AI ) );
					wcscpy ( (wchar_t*)AI.AdapterBuffer, L"\\Device\\");
					wcscat ( (wchar_t*)AI.AdapterBuffer, wchKey );
					AI.AdapterNameSize = ( wcslen ( (wchar_t*)AI.AdapterBuffer ) + 1 ) << 1;
					AI.LocalIp = 0;

					RetList.push_back( AI );
				}
			} 
		}
		else
		*/
		{
			// Winnt4.0
			if ( ERROR_SUCCESS == RegOpenKey( HKEY_LOCAL_MACHINE, "Software\\Microsoft\\Windows NT\\CurrentVersion\\NetworkCards", &hKey ) )
			{
				for ( i = 0, retCode = ERROR_SUCCESS; retCode == ERROR_SUCCESS; i++ )
				{
					HKEY hSubKey = NULL;
					KeyLength = MAX_PATH;
					retCode = RegEnumKeyExW(hKey, i, wchKey, &KeyLength, NULL, NULL, NULL, &ftLastWriteTime );
					
					if ( retCode == ERROR_SUCCESS )
					{
						retCode = RegOpenKeyW(hKey, wchKey, &hSubKey );
					}

					if ( retCode == ERROR_SUCCESS )
					{			
						KeyLength = MAX_PATH;
						DWORD	type = REG_SZ;

						if ( ERROR_SUCCESS == RegQueryValueExW( 
							hSubKey, 
							L"ServiceName", 
							NULL,
							&type,
							(LPBYTE)wchKey, 
							(ULONG*)&KeyLength ) )
						{
							memset ( &AI , 0, sizeof ( AI ) );
							wcscpy ( (wchar_t*)AI.AdapterBuffer, L"\\Device\\");
							wcscat ( (wchar_t*)AI.AdapterBuffer, wchKey );
							AI.AdapterNameSize = ( wcslen ( (wchar_t*)AI.AdapterBuffer ) + 1 ) << 1;
							AI.LocalIp = 0;
							
							// Если открывается и не Hidden, тогда добавляем для проверки.
							if ( scan( (wchar_t*)wchKey ) && !IsHidden(hSubKey) )
								RetList.push_back( AI );
						}
					}

					if ( hSubKey )
						RegCloseKey( hSubKey );
				}
			}			
		}
	}
	else
	{
		if ( ERROR_SUCCESS == RegOpenKey( HKEY_LOCAL_MACHINE, W9X_ADAPTER_KEY, &hKey ) )
		{			
			for (i = 0, retCode = ERROR_SUCCESS; retCode == ERROR_SUCCESS; i++ )
			{ 
				KeyLength = MAX_PATH;

				retCode = RegEnumKeyExA(hKey, i, achKey, &KeyLength, NULL, NULL, NULL, &ftLastWriteTime);
				
				if ( ERROR_SUCCESS == retCode )
				{
					memset ( &AI , 0, sizeof ( AI ) );					
					strcpy ( AI.AdapterBuffer, achKey );
					AI.AdapterNameSize = strlen ( achKey ) + 1;
					AI.LocalIp = 0;

					RetList.push_back( AI );
				}				
			} 
		}
	}

	if ( hKey )
	{
		RegCloseKey( hKey );
	}

	return RetList;
}
Exemple #7
0
/// \brief Read registry string.
/// This also supports a means to look for high-versioned keys by use
/// of a $VERSION placeholder in the key path.
/// $VERSION in the key path is a placeholder for the version number,
/// causing the highest value path to be searched for and used.
/// I.e. "HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\VisualStudio\\$VERSION".
/// There can be additional characters in the component.  Only the numeric
/// characters are compared.
static bool getSystemRegistryString(const char *keyPath, const char *valueName,
                                    char *value, size_t maxLength) {
  HKEY hRootKey = NULL;
  HKEY hKey = NULL;
  const char* subKey = NULL;
  DWORD valueType;
  DWORD valueSize = maxLength - 1;
  long lResult;
  bool returnValue = false;

  if (strncmp(keyPath, "HKEY_CLASSES_ROOT\\", 18) == 0) {
    hRootKey = HKEY_CLASSES_ROOT;
    subKey = keyPath + 18;
  } else if (strncmp(keyPath, "HKEY_USERS\\", 11) == 0) {
    hRootKey = HKEY_USERS;
    subKey = keyPath + 11;
  } else if (strncmp(keyPath, "HKEY_LOCAL_MACHINE\\", 19) == 0) {
    hRootKey = HKEY_LOCAL_MACHINE;
    subKey = keyPath + 19;
  } else if (strncmp(keyPath, "HKEY_CURRENT_USER\\", 18) == 0) {
    hRootKey = HKEY_CURRENT_USER;
    subKey = keyPath + 18;
  } else {
    return false;
  }

  const char *placeHolder = strstr(subKey, "$VERSION");
  char bestName[256];
  bestName[0] = '\0';
  // If we have a $VERSION placeholder, do the highest-version search.
  if (placeHolder) {
    const char *keyEnd = placeHolder - 1;
    const char *nextKey = placeHolder;
    // Find end of previous key.
    while ((keyEnd > subKey) && (*keyEnd != '\\'))
      keyEnd--;
    // Find end of key containing $VERSION.
    while (*nextKey && (*nextKey != '\\'))
      nextKey++;
    size_t partialKeyLength = keyEnd - subKey;
    char partialKey[256];
    if (partialKeyLength > sizeof(partialKey))
      partialKeyLength = sizeof(partialKey);
    strncpy(partialKey, subKey, partialKeyLength);
    partialKey[partialKeyLength] = '\0';
    HKEY hTopKey = NULL;
    lResult = RegOpenKeyExA(hRootKey, partialKey, 0, KEY_READ, &hTopKey);
    if (lResult == ERROR_SUCCESS) {
      char keyName[256];
      int bestIndex = -1;
      double bestValue = 0.0;
      DWORD index, size = sizeof(keyName) - 1;
      for (index = 0; RegEnumKeyExA(hTopKey, index, keyName, &size, NULL,
          NULL, NULL, NULL) == ERROR_SUCCESS; index++) {
        const char *sp = keyName;
        while (*sp && !isdigit(*sp))
          sp++;
        if (!*sp)
          continue;
        const char *ep = sp + 1;
        while (*ep && (isdigit(*ep) || (*ep == '.')))
          ep++;
        char numBuf[32];
        strncpy(numBuf, sp, sizeof(numBuf) - 1);
        numBuf[sizeof(numBuf) - 1] = '\0';
        double value = strtod(numBuf, NULL);

        // Check if InstallDir key value exists.
        bool isViableVersion = false;

        lResult = RegOpenKeyExA(hTopKey, keyName, 0, KEY_READ, &hKey);
        if (lResult == ERROR_SUCCESS) {
          lResult = RegQueryValueExA(hKey, valueName, NULL, NULL, NULL, NULL);
          if (lResult == ERROR_SUCCESS)
            isViableVersion = true;
          RegCloseKey(hKey);
        }

        if (isViableVersion && (value > bestValue)) {
          bestIndex = (int)index;
          bestValue = value;
          strcpy(bestName, keyName);
        }
        size = sizeof(keyName) - 1;
      }
      // If we found the highest versioned key, open the key and get the value.
      if (bestIndex != -1) {
        // Append rest of key.
        strncat(bestName, nextKey, sizeof(bestName) - 1);
        bestName[sizeof(bestName) - 1] = '\0';
        // Open the chosen key path remainder.
        lResult = RegOpenKeyExA(hTopKey, bestName, 0, KEY_READ, &hKey);
        if (lResult == ERROR_SUCCESS) {
          lResult = RegQueryValueExA(hKey, valueName, NULL, &valueType,
            (LPBYTE)value, &valueSize);
          if (lResult == ERROR_SUCCESS)
            returnValue = true;
          RegCloseKey(hKey);
        }
      }
      RegCloseKey(hTopKey);
    }
  } else {
    lResult = RegOpenKeyExA(hRootKey, subKey, 0, KEY_READ, &hKey);
    if (lResult == ERROR_SUCCESS) {
      lResult = RegQueryValueExA(hKey, valueName, NULL, &valueType,
        (LPBYTE)value, &valueSize);
      if (lResult == ERROR_SUCCESS)
        returnValue = true;
      RegCloseKey(hKey);
    }
  }
  return returnValue;
}
Exemple #8
0
/***********************************************************************
 *		VideoCapDriverDescAndVer	[MSVIDEO.22]
 */
DWORD WINAPI VideoCapDriverDescAndVer16(WORD nr, LPSTR buf1, WORD buf1len,
                                        LPSTR buf2, WORD buf2len)
{
    static const char version_info_spec[] = "\\StringFileInfo\\040904E4\\FileDescription";
    DWORD	verhandle;
    DWORD	infosize;
    UINT	subblocklen;
    char	*s, buf[2048], fn[260];
    LPBYTE	infobuf;
    LPVOID	subblock;
    DWORD	i, cnt = 0, lRet;
    DWORD	bufLen, fnLen;
    FILETIME	lastWrite;
    HKEY	hKey;
    BOOL        found = FALSE;

    TRACE("(%d,%p,%d,%p,%d)\n", nr, buf1, buf1len, buf2, buf2len);
    lRet = RegOpenKeyExA(HKEY_LOCAL_MACHINE, HKLM_DRIVERS32, 0, KEY_QUERY_VALUE, &hKey);
    if (lRet == ERROR_SUCCESS) 
    {
	RegQueryInfoKeyA( hKey, 0, 0, 0, &cnt, 0, 0, 0, 0, 0, 0, 0);
	for (i = 0; i < cnt; i++) 
	{
	    bufLen = sizeof(buf) / sizeof(buf[0]);
	    lRet = RegEnumKeyExA(hKey, i, buf, &bufLen, 0, 0, 0, &lastWrite);
	    if (lRet != ERROR_SUCCESS) continue;
	    if (strncasecmp(buf, "vid", 3)) continue;
	    if (nr--) continue;
	    fnLen = sizeof(fn);
	    lRet = RegQueryValueExA(hKey, buf, 0, 0, (LPBYTE)fn, &fnLen);
	    if (lRet == ERROR_SUCCESS) found = TRUE;
	    break;
	}
    	RegCloseKey( hKey );
    } 

    /* search system.ini if not found in the registry */
    if (!found && GetPrivateProfileStringA("drivers32", NULL, NULL, buf, sizeof(buf), "system.ini"))
    {
	for (s = buf; *s; s += strlen(s) + 1)
	{
	    if (strncasecmp(s, "vid", 3)) continue;
	    if (nr--) continue;
	    if (GetPrivateProfileStringA("drivers32", s, NULL, fn, sizeof(fn), "system.ini"))
		found = TRUE;
	    break;
	}
    }

    if (!found)
    {
        TRACE("No more VID* entries found nr=%d\n", nr);
        return 20;
    }
    infosize = GetFileVersionInfoSizeA(fn, &verhandle);
    if (!infosize) 
    {
        TRACE("%s has no fileversioninfo.\n", fn);
        return 18;
    }
    infobuf = HeapAlloc(GetProcessHeap(), 0, infosize);
    if (GetFileVersionInfoA(fn, verhandle, infosize, infobuf)) 
    {
        /* Yes, two space behind : */
        /* FIXME: test for buflen */
        snprintf(buf2, buf2len, "Version:  %d.%d.%d.%d\n",
                ((WORD*)infobuf)[0x0f],
                ((WORD*)infobuf)[0x0e],
                ((WORD*)infobuf)[0x11],
                ((WORD*)infobuf)[0x10]
	    );
        TRACE("version of %s is %s\n", fn, buf2);
    }
    else 
    {
        TRACE("GetFileVersionInfoA failed for %s.\n", fn);
        lstrcpynA(buf2, fn, buf2len); /* msvideo.dll appears to copy fn*/
    }
    /* FIXME: language problem? */
    if (VerQueryValueA(	infobuf,
                        version_info_spec,
                        &subblock,
                        &subblocklen
            )) 
    {
        UINT copylen = min(subblocklen,buf1len-1);
        memcpy(buf1, subblock, copylen);
        buf1[copylen] = '\0';
        TRACE("VQA returned %s\n", (LPCSTR)subblock);
    }
    else 
    {
        TRACE("VQA did not return on query \\StringFileInfo\\040904E4\\FileDescription?\n");
        lstrcpynA(buf1, fn, buf1len); /* msvideo.dll appears to copy fn*/
    }
    HeapFree(GetProcessHeap(), 0, infobuf);
    return 0;
}
Exemple #9
0
static bool CheckRegKeyWMe(const char * keyName, const char * prefix, bool& dmaDisabled, std::vector<std::string>& dmaDisabledlist)
{
	dmaDisabled = false;

    char  achKey[MAX_VALUE_NAME]; 
    DWORD i;
    LONG retCode;

	char * keyName1 = "Config Manager\\Enum";

    HKEY hKey;
    HKEY hKey1;
// **CodeWizzard** - Violation:  More Effective C++ item 2  - Prefer C++-style cast
    if (ERROR_SUCCESS != RegOpenKeyExA(HKEY_DYN_DATA, keyName1,
                                      0, KEY_QUERY_VALUE|KEY_ENUMERATE_SUB_KEYS, &hKey1))
		return false;

	std::set<std::string> currentHardwareIDs;

	DWORD size;
	DWORD max_path = MAX_VALUE_NAME;

    for (i = 0, retCode = ERROR_SUCCESS; 
            retCode == ERROR_SUCCESS; i++) 
    {
	  max_path = MAX_VALUE_NAME;
		retCode = RegEnumKeyExA(hKey1, i, achKey, &max_path, 0, 0, 0, 0);
        if (retCode == ERROR_SUCCESS) 
        {
			char subkey[MAX_VALUE_NAME];
			sonic::strncpy_safe(subkey, keyName1, sizeof(subkey));
			sonic::strncat_safe(subkey, "\\", sizeof(subkey));
			sonic::strncat_safe(subkey, achKey, sizeof(subkey));
// **CodeWizzard** - Violation:  More Effective C++ item 2  - Prefer C++-style cast
			if (ERROR_SUCCESS != RegOpenKeyExA(HKEY_DYN_DATA, subkey,
                                              0, KEY_QUERY_VALUE, &hKey))
				continue;

			char hardWareKeyName[] = "HardWareKey";
			size = 0x0;
			if (ERROR_SUCCESS != RegQueryValueExA(hKey, hardWareKeyName, 0, 0, 0, &size))
				continue;

			char* pHardWareKeyValue = new char[size];
			if (ERROR_SUCCESS != RegQueryValueExA(hKey, hardWareKeyName, 0, 0,
				                                reinterpret_cast<LPBYTE>(pHardWareKeyValue), &size))
			{
				delete [] pHardWareKeyValue;
				continue;

          	} 
			RegCloseKey(hKey);

			std::string hardwareID(pHardWareKeyValue);
            std::string subHardwareID = hardwareID.substr(0,5);
			delete [] pHardWareKeyValue;
            if(subHardwareID != prefix)
				continue;
      
			size_t pos1 = 5;
			size_t pos2 = hardwareID.find_first_of('\\', pos1+1);
			if (pos2 == std::string::npos)
				continue;
			currentHardwareIDs.insert(hardwareID.substr(pos1, pos2-pos1));
		}
	}
    
	RegCloseKey(hKey1);

	if (currentHardwareIDs.size() == 0)
		return false;

    if (ERROR_SUCCESS != RegOpenKeyExA(HKEY_LOCAL_MACHINE, keyName,
                                      0, KEY_QUERY_VALUE|KEY_ENUMERATE_SUB_KEYS, &hKey1))
		return false;

    for (i = 0, retCode = ERROR_SUCCESS; 
            retCode == ERROR_SUCCESS; i++) 
    {
        max_path = MAX_VALUE_NAME;
		if( (retCode = RegEnumKeyExA(hKey1, i, achKey, &max_path, 0, 0, 0, 0)) == ERROR_SUCCESS )
        {
			//try to get the dma value
			char subkey[MAX_VALUE_NAME];
			sonic::strncpy_safe(subkey, keyName, sizeof(subkey));
			sonic::strncat_safe(subkey, "\\", sizeof(subkey));
			sonic::strncat_safe(subkey, achKey, sizeof(subkey));
			if (ERROR_SUCCESS != RegOpenKeyExA(HKEY_LOCAL_MACHINE, subkey,
                                              0, KEY_QUERY_VALUE|KEY_ENUMERATE_SUB_KEYS, &hKey))
				continue;

			
			for(DWORD j=0, retCode1 = ERROR_SUCCESS; retCode1==ERROR_SUCCESS; j++)
			{
				max_path = MAX_VALUE_NAME;
				if( (retCode1 = RegEnumKeyExA(hKey, j, achKey, &max_path, 0, 0, 0, 0)) == ERROR_SUCCESS )
				{
					char skey[MAX_VALUE_NAME];
					HKEY hsKey;
					sonic::strncpy_safe(skey, subkey, sizeof(skey));
					sonic::strncat_safe(skey, "\\", sizeof(skey));
					sonic::strncat_safe(skey, achKey, sizeof(skey));
					if(ERROR_SUCCESS != RegOpenKeyExA( HKEY_LOCAL_MACHINE, skey,
						0, KEY_QUERY_VALUE, &hsKey ))
						continue;

					char dmaValueName[] = "DMACurrentlyUsed";
					DWORD dmaValue = 0x0;
					size = sizeof(DWORD);
					if(ERROR_SUCCESS != RegQueryValueExA(hsKey, dmaValueName, 0, 0, (LPBYTE)&dmaValue, &size))
					{
						RegCloseKey(hsKey);
						continue;
					}

					if(dmaValue == 0x0) //DMA is disabled
					{
						char hardWareKeyName[] = "HardwareID";
						size = 0x0;
						if(ERROR_SUCCESS != RegQueryValueExA(hsKey, hardWareKeyName, 0, 0, 0, &size))
						{
							RegCloseKey(hsKey);
							continue;
						}

						char* pHardWareKeyValue = new char[size];
						if(ERROR_SUCCESS != RegQueryValueExA(hsKey, hardWareKeyName, 0, 0,
							(LPBYTE)pHardWareKeyValue, &size))
						{
							RegCloseKey(hsKey);
							delete [] pHardWareKeyValue;
							continue;
						}

						size = 0x0;
						char deviceDesc[] = "DeviceDesc";
						char * pDeviceDesc = 0;
						if(ERROR_SUCCESS == RegQueryValueExA(hsKey, deviceDesc, 0, 0, 0, &size))
						{
							pDeviceDesc = new char[size];
							RegQueryValueExA(hsKey, deviceDesc, 0, 0, (LPBYTE)pDeviceDesc, &size);
						}

						RegCloseKey(hsKey);

						std::string hardwareID(pHardWareKeyValue); 
						delete [] pHardWareKeyValue;
						size_t pos = hardwareID.find_first_of(',', 0);
						if (pos == std::string::npos)
						{
							delete [] pDeviceDesc;
							continue;
						}

						std::string subHardwareID = hardwareID.substr(0,pos);
						if(currentHardwareIDs.find(subHardwareID) ==  currentHardwareIDs.end())
						{
							delete [] pDeviceDesc;
							continue;
						}

						if(pDeviceDesc)
						{
							std::string szDeviceDesc(pDeviceDesc);
							dmaDisabledlist.push_back(szDeviceDesc);
							delete [] pDeviceDesc;
						}

						dmaDisabled = true;
					}	
				}
			}
			RegCloseKey(hKey);
		}
    } //for

	RegCloseKey(hKey1);
    return true;
}
Exemple #10
0
static bool CheckRegKeyWXP(bool& dmaDisabled, std::vector<std::string>& dmaDisabledlist)
{
	dmaDisabled = false;
	HKEY hKey;
	LONG retCode = ERROR_SUCCESS;
	//HKLM\HARDWARE\DEVICEMAP\Scsi
	if(ERROR_SUCCESS != RegOpenKeyExA( HKEY_LOCAL_MACHINE, "HARDWARE\\DEVICEMAP\\Scsi",
		0, KEY_QUERY_VALUE|KEY_ENUMERATE_SUB_KEYS, &hKey ))
		return false;

	char keyBuf[MAX_VALUE_NAME];
	DWORD max_path = MAX_VALUE_NAME;

	retCode = RegEnumKeyExA(hKey, 0, keyBuf, &max_path, 0, 0, 0, 0);
	if(retCode != ERROR_SUCCESS) 
	{
		RegCloseKey(hKey);
		return false;
	}	

	HKEY hPortKey;
	for(DWORD nPort=1, retCode=ERROR_SUCCESS; retCode==ERROR_SUCCESS; nPort++)
	{
		//HKLM\HARDWARE\DEVICEMAP\Scsi\Scsi Port 0...
		if( ERROR_SUCCESS == RegOpenKeyExA(hKey, keyBuf, 0, KEY_QUERY_VALUE|KEY_ENUMERATE_SUB_KEYS, &hPortKey) )
		{
			size_t dmaValue = 0;
			DWORD size = sizeof(DWORD);
			//DMAEnabled
			if( ERROR_SUCCESS != RegQueryValueExA(hPortKey, "DMAEnabled", 0, 0, (LPBYTE)&dmaValue, &size) )
			{
				RegCloseKey(hPortKey);
				RegCloseKey(hKey);
				return false;
			}
			if(dmaValue == 0x0)
			{
				dmaDisabled = true;
				HKEY hBusKey;
				for(DWORD nBus=0,retCode=ERROR_SUCCESS;retCode==ERROR_SUCCESS;nBus++)
				{
					max_path = MAX_VALUE_NAME;
					keyBuf[0] = '\0';
					retCode = RegEnumKeyExA(hPortKey, nBus, keyBuf, &max_path, 0, 0, 0, 0);
					if( retCode == ERROR_SUCCESS )
					{
						//HKLM\HARDWARE\DEVICEMAP\Scsi\Scsi Port 0\Scsi Bus 0...
						if( ERROR_SUCCESS == RegOpenKeyExA(hPortKey, keyBuf, 0, KEY_QUERY_VALUE|KEY_ENUMERATE_SUB_KEYS, &hBusKey) )
						{
							HKEY hTargetKey;
							for(DWORD nTarget=0,retCode=ERROR_SUCCESS;retCode==ERROR_SUCCESS;nTarget++)
							{
								max_path = MAX_VALUE_NAME;
								keyBuf[0] = '\0';
								retCode = RegEnumKeyExA(hBusKey, nTarget, keyBuf, &max_path, 0, 0, 0, 0);
								if( retCode==ERROR_SUCCESS )
								{
									std::string targetValue(keyBuf);
									if(targetValue.find("Target Id")==std::string::npos)
										continue;
									//HKLM\HARDWARE\DEVICEMAP\Scsi\Scsi Port 0\Scsi Bus 0\Target Id 0...
									targetValue += "\\Logical Unit Id 0";
									if( ERROR_SUCCESS == RegOpenKeyExA(hBusKey, targetValue.c_str(), 0, KEY_QUERY_VALUE|KEY_ENUMERATE_SUB_KEYS, &hTargetKey) )
									{
										max_path = MAX_VALUE_NAME;
										keyBuf[0] = '\0';
										retCode = RegQueryValueExA(hTargetKey, "Identifier", 0, 0, (LPBYTE)keyBuf, &max_path);
										if( retCode==ERROR_SUCCESS )
										{
											dmaDisabledlist.push_back(std::string(keyBuf));
										}
										RegCloseKey(hTargetKey);
									}
								}
							}
							RegCloseKey(hBusKey);
						}
					}
				}
			}
			RegCloseKey(hPortKey);
		}
		max_path = MAX_VALUE_NAME;
		keyBuf[0] = '\0';
		retCode = RegEnumKeyExA(hKey, nPort, keyBuf, &max_path, 0, 0, 0, 0);
	}
	RegCloseKey(hKey);
	return true;
}
Exemple #11
0
BOOL QCWWAN_GetControlFileName
(
   PCHAR DeviceFriendlyName,
   PCHAR ControlFileName
)
{
   HKEY hTestKey;


   if (RegOpenKeyExA
       (
          HKEY_LOCAL_MACHINE,
          QCNET_REG_HW_KEY,
          0,
          KEY_READ,
          &hTestKey
       ) == ERROR_SUCCESS
      )
   {
       CHAR    achKey[MAX_KEY_LENGTH];   // buffer for subkey name
       DWORD    cbName;                   // size of name string
       CHAR    achClass[MAX_PATH] = "";  // buffer for class name
       DWORD    cchClassName = MAX_PATH;  // size of class string
       DWORD    cSubKeys=0;               // number of subkeys
       DWORD    cbMaxSubKey;              // longest subkey size
       DWORD    cchMaxClass;              // longest class string
       DWORD    cValues;              // number of values for key
       DWORD    cchMaxValue;          // longest value name
       DWORD    cbMaxValueData;       // longest value data
       DWORD    cbSecurityDescriptor; // size of security descriptor
       FILETIME ftLastWriteTime;      // last write time
       DWORD    i, retCode;
       DWORD    cchValue = MAX_VALUE_NAME;

       // Get the class name and the value count.
       retCode = RegQueryInfoKeyA
                 (
                    hTestKey,                    // key handle
                    achClass,                // buffer for class name
                    &cchClassName,           // size of class string
                    NULL,                    // reserved
                    &cSubKeys,               // number of subkeys
                    &cbMaxSubKey,            // longest subkey size
                    &cchMaxClass,            // longest class string
                    &cValues,                // number of values for this key
                    &cchMaxValue,            // longest value name
                    &cbMaxValueData,         // longest value data
                    &cbSecurityDescriptor,   // security descriptor
                    &ftLastWriteTime         // last write time
                 );

       // Enumerate the subkeys, until RegEnumKeyEx fails.
       if (cSubKeys)
       {
           for (i=0; i<cSubKeys; i++)
           {
               cbName = MAX_KEY_LENGTH;
               retCode = RegEnumKeyExA
                         (
                            hTestKey, i,
                            achKey,
                            &cbName,
                            NULL,
                            NULL,
                            NULL,
                            &ftLastWriteTime
                                  );
               if (retCode == ERROR_SUCCESS)
               {
                   BOOL result;

                   // _tprintf(TEXT("A-(%d) %s\n"), i+1, achKey);
                   result = QueryUSBDeviceKeys(achKey, DeviceFriendlyName, ControlFileName);
                   if (result == TRUE)
                   {
                      // printf("QueryKey: TRUE\n");
                      return TRUE;
                   }
               }
           }
       }

      RegCloseKey(hTestKey);

      return retCode;
   }

   return FALSE;
}
Exemple #12
0
BOOL QueryKey
(
   HKEY  hKey,
   PCHAR DeviceFriendlyName,
   PCHAR ControlFileName,
   PCHAR FullKeyName
)
{ 
    CHAR    achKey[MAX_KEY_LENGTH];   // buffer for subkey name
    DWORD    cbName;                   // size of name string 
    CHAR    achClass[MAX_PATH] = "";  // buffer for class name 
    DWORD    cchClassName = MAX_PATH;  // size of class string 
    DWORD    cSubKeys=0;               // number of subkeys 
    DWORD    cbMaxSubKey;              // longest subkey size 
    DWORD    cchMaxClass;              // longest class string 
    DWORD    cValues;              // number of values for key 
    DWORD    cchMaxValue;          // longest value name 
    DWORD    cbMaxValueData;       // longest value data 
    DWORD    cbSecurityDescriptor; // size of security descriptor 
    FILETIME ftLastWriteTime;      // last write time 
    char     fullKeyName[MAX_KEY_LENGTH];
 
    DWORD i, retCode; 
 
    DWORD cchValue = MAX_VALUE_NAME; 
 
    // Get the class name and the value count. 
    retCode = RegQueryInfoKeyA
              (
                 hKey,                    // key handle 
                 achClass,                // buffer for class name 
                 &cchClassName,           // size of class string 
                 NULL,                    // reserved 
                 &cSubKeys,               // number of subkeys 
                 &cbMaxSubKey,            // longest subkey size 
                 &cchMaxClass,            // longest class string 
                 &cValues,                // number of values for this key 
                 &cchMaxValue,            // longest value name 
                 &cbMaxValueData,         // longest value data 
                 &cbSecurityDescriptor,   // security descriptor 
                 &ftLastWriteTime         // last write time 
              );
 
    // Enumerate the subkeys, until RegEnumKeyEx fails.
    
    if (cSubKeys)
    {
        for (i=0; i<cSubKeys; i++) 
        { 
            cbName = MAX_KEY_LENGTH;
            retCode = RegEnumKeyExA
                      (
                         hKey, i,
                         achKey, 
                         &cbName, 
                         NULL, 
                         NULL, 
                         NULL, 
                         &ftLastWriteTime
                      ); 
            if (retCode == ERROR_SUCCESS) 
            {
                BOOL result;

                // _tprintf(TEXT("C-(%d) %s\n"), i+1, achKey);
                sprintf(fullKeyName, "%s\\%s", FullKeyName, achKey);
                result = FindDeviceInstance(fullKeyName, DeviceFriendlyName, ControlFileName);
                if (result == TRUE)
                {
                   // printf("QueryKey: TRUE\n");
                   return TRUE;
                }
            }
        }
    }

    // printf("QueryKey: FALSE\n");

    return FALSE;
}  // QueryKey
	//////////////////////////////////////////////////////////////////////////////////////////////// 
	// out_SubKeys will be empty of no sub-keys were found
	void RetrieveRegistryListOfSubkeys( const HKEY in_hkey, std::vector<std::string> &out_SubKeys )
	{
		// The following code is from http://msdn.microsoft.com/en-us/library/ms724256(VS.85).aspx

		CHAR    achKey[MAX_KEY_LENGTH];   // buffer for subkey name
		DWORD    cbName;                   // size of name string 
		CHAR     achClass[MAX_PATH] = "";  // buffer for class name 
		DWORD    cchClassName = MAX_PATH;  // size of class string 
		DWORD    cSubKeys=0;               // number of subkeys 
		DWORD    cbMaxSubKey;              // longest subkey size 
		DWORD    cchMaxClass;              // longest class string 
		DWORD    cValues;                  // number of values for key 
		DWORD    cchMaxValue;              // longest value name 
		DWORD    cbMaxValueData;           // longest value data 
		DWORD    cbSecurityDescriptor;     // size of security descriptor 
		FILETIME ftLastWriteTime;          // last write time 
 
		DWORD i, retCode; 
 
		//WCHAR  achValue[MAX_VALUE_NAME]; 
		//DWORD cchValue = MAX_VALUE_NAME; 
 
		// Get the class name and the value count. 
		retCode = RegQueryInfoKeyA(
			in_hkey,                    // key handle 
			achClass,                // buffer for class name 
			&cchClassName,           // size of class string 
			NULL,                    // reserved 
			&cSubKeys,               // number of subkeys 
			&cbMaxSubKey,            // longest subkey size 
			&cchMaxClass,            // longest class string 
			&cValues,                // number of values for this key 
			&cchMaxValue,            // longest value name 
			&cbMaxValueData,         // longest value data 
			&cbSecurityDescriptor,   // security descriptor 
			&ftLastWriteTime);       // last write time 
 
		// Enumerate the subkeys, until RegEnumKeyEx fails.
    
		if (cSubKeys)
		{
			//printf( "\nNumber of subkeys: %d\n", cSubKeys);

			for (i=0; i<cSubKeys; i++) 
			{ 
				cbName = MAX_KEY_LENGTH;
				retCode = RegEnumKeyExA(in_hkey, i,
						 achKey, 
						 &cbName, 
						 NULL, 
						 NULL, 
						 NULL, 
						 &ftLastWriteTime); 
				if (retCode == ERROR_SUCCESS) 
				{
					//wprintf(TEXT("(%d) %s\n"), i+1, achKey);
					out_SubKeys.push_back(achKey);
				}
			}
		} 

	}