Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

808 lines
18 KiB

/***************************************************************************
Name : REGISTRY.C
Comment : INIfile handling
Revision Log
Date Name Description
-------- ----- ---------------------------------------------------------
***************************************************************************/
#include "prep.h"
#include "efaxcb.h"
#include "t30.h"
#include "hdlc.h"
#include "debug.h"
#include "glbproto.h"
#ifdef USE_REGISTRY
// The default database to us
# define DATABASE_KEY HKEY_LOCAL_MACHINE
// These are NOT localizable items.
# define szKEYPREFIX "SOFTWARE\\Microsoft\\Fax\\Devices"
# define szKEYCLASS "DATA"
DWORD my_atoul(LPSTR lpsz);
#else // !USE_REGISTRY
BOOL expand_key(DWORD dwKey, LPSTR FAR *lplpszKey,
LPSTR FAR *lplpszProfileName);
#endif // !USE_REGISTRY
ULONG_PTR ProfileOpen(DWORD dwProfileID, LPSTR lpszSection, DWORD dwFlags)
{
ULONG_PTR dwRet = 0;
#ifdef USE_REGISTRY
char rgchKey[128];
HKEY hKey=0;
HKEY hBaseKey = DATABASE_KEY;
LONG l;
LPSTR lpszPrefix;
DWORD sam=0;
BG_CHK(sizeof(hKey)<=sizeof(ULONG_PTR));
if (dwProfileID==OEM_BASEKEY)
{
hBaseKey = HKEY_LOCAL_MACHINE;
lpszPrefix= ""; // we don't prepend szKEYPREFIX
if (!lpszSection) goto failure;
}
else if (lpszSection)
{
lpszPrefix= szKEYPREFIX "\\";
}
else
{
lpszPrefix= szKEYPREFIX;
lpszSection="";
}
if ((lstrlen(lpszPrefix)+lstrlen(lpszSection))>=sizeof(rgchKey))
goto failure;
lstrcpy(rgchKey, lpszPrefix);
lstrcat(rgchKey, lpszSection);
sam = 0;
if (dwFlags &fREG_READ) sam |= KEY_READ;
if (dwFlags &fREG_WRITE) sam |= KEY_WRITE;
if (dwFlags & fREG_CREATE)
{
DWORD dwDisposition=0;
DWORD dwOptions = (dwFlags & fREG_VOLATILE)
?REG_OPTION_VOLATILE
:REG_OPTION_NON_VOLATILE;
sam = KEY_READ | KEY_WRITE; // we force sam to this when creating.
l = RegCreateKeyEx(
hBaseKey, // handle of open key
rgchKey, // address of name of subkey to open
0, // reserved
szKEYCLASS, // address of class string
dwOptions, // special options flag
sam, // desired security access
NULL, // address of key security structure
&hKey, // address of buffer for opened handle
&dwDisposition // address of dispostion value buffer
);
}
else
{
l = RegOpenKeyEx(
hBaseKey, // handle of open key
rgchKey, // address of name of subkey to open
0, // reserved
sam , // desired security access
&hKey // address of buffer for opened handle
);
}
if (l!=ERROR_SUCCESS)
{
//LOG((_ERR, "RegCreateKeyEx returns error %ld\n", (long) l));
goto failure;
}
dwRet = (ULONG_PTR) hKey;
#else // !USE_REGISTRY
LPSTR lpszFile= szINIFILE;
ATOM aSection, aProfile;
// NULL lpszSection not supported.
if (!lpszSection) goto failure;
if (!(aSection = GlobalAddAtom(lpszSection)))
goto failure;
if (!(aProfile = GlobalAddAtom(lpszFile)))
{GlobalDeleteAtom(aSection); goto failure;}
dwRet = MAKELONG(aSection, aProfile);
#endif // !USE_REGISTRY
BG_CHK(dwRet);
return dwRet;
failure:
return 0;
}
UINT
ProfileListGetInt(
ULONG_PTR KeyList[10],
LPSTR lpszValueName,
UINT uDefault
)
{
int i;
int Num=0;
UINT uRet = uDefault;
BOOL fExist = 0;
for (i=0; i<10; i++) {
if (KeyList[i] == 0) {
Num = i-1;
break;
}
}
for (i=Num; i>=0; i--) {
uRet = ProfileGetInt (KeyList[i], lpszValueName, uDefault, &fExist);
if (fExist) {
return uRet;
}
}
return uRet;
}
UINT ProfileGetInt(ULONG_PTR dwKey, LPSTR lpszValueName, UINT uDefault, BOOL *fExist)
{
UINT uRet = uDefault;
char rgchBuf[128];
DWORD dwType;
DWORD dwcbSize=sizeof(rgchBuf);
LONG l = RegQueryValueEx(
(HKEY) dwKey,
lpszValueName,
0,
&dwType,
rgchBuf,
&dwcbSize
);
if (fExist) {
*fExist = 0;
}
if (l!=ERROR_SUCCESS)
{
//LOG((_ERR, "RegQueryValueEx returned error %ld\n", (long) l));
goto end;
}
if (fExist) {
*fExist = 1;
}
if (dwType != REG_SZ)
{
//LOG((_ERR, "RegQueryValueEx value type not string:0x%lx\n",
// (unsigned long) dwType));
goto end;
}
uRet = (UINT) my_atoul(rgchBuf);
end:
return uRet;
}
DWORD ProfileGetString(ULONG_PTR dwKey, LPSTR lpszValueName,
LPSTR lpszDefault, LPSTR lpszBuf , DWORD dwcbMax)
{
DWORD dwRet = 0;
#ifdef USE_REGISTRY
DWORD dwType;
LONG l = RegQueryValueEx(
(HKEY) dwKey,
lpszValueName,
0,
&dwType,
lpszBuf,
&dwcbMax
);
if (l!=ERROR_SUCCESS)
{
//LOG((_ERR, "RegQueryValueEx returned error %ld\n", (long) l));
goto copy_default;
}
if (dwType != REG_SZ)
{
//LOG((_ERR, "RegQueryValueEx value type not string:0x%lx\n",
// (unsigned long) dwType));
goto copy_default;
}
// Make sure we null-terminate the string and return the true string
// length..
if (dwcbMax) {lpszBuf[dwcbMax-1]=0; dwcbMax = (DWORD) lstrlen(lpszBuf);}
dwRet = dwcbMax;
goto end;
#else // USE_REGISTRY
LPSTR lpszKey;
LPSTR lpszProfileName;
if (!expand_key(dwKey, &lpszKey, &lpszProfileName)) goto copy_default;
dwRet = GetPrivateProfileString(lpszKey, lpszValueName,
lpszDefault, lpszBuf , (INT) dwcbMax,
lpszProfileName);
goto end;
#endif // USE_REGISTRY
BG_CHK(FALSE);
copy_default:
dwRet = 0;
if (!lpszDefault || !*lpszDefault)
{
if (dwcbMax) *lpszBuf=0;
}
else
{
UINT cb = _fstrlen(lpszDefault)+1;
if (cb>(UINT)dwcbMax) cb=dwcbMax;
if (cb)
{
_fmemcpy(lpszBuf, lpszDefault, cb);
lpszBuf[cb-1]=0;
dwRet = cb-1;
}
}
// fall through...
end:
return dwRet;
}
BOOL
ProfileWriteString(
ULONG_PTR dwKey,
LPSTR lpszValueName,
LPSTR lpszBuf,
BOOL fRemoveCR
)
{
// NOTE: If lpszValueName is null, delete the key. (can't do this in,
// the registry, unfortunately).
// If lpszBuf is null pointer -- "delete" this value.
BOOL fRet=FALSE;
#ifdef USE_REGISTRY
LONG l;
if (!lpszValueName) goto end;
if (!lpszBuf)
{
// delete value...
l = RegDeleteValue((HKEY) dwKey, lpszValueName);
if (l!=ERROR_SUCCESS) goto end;
}
else
{
if (fRemoveCR) {
RemoveCR (lpszBuf);
}
l = RegSetValueEx((HKEY) dwKey, lpszValueName, 0, REG_SZ,
lpszBuf, lstrlen(lpszBuf)+1);
if (l!=ERROR_SUCCESS)
{
//LOG((_ERR,
// "RegSetValueEx(\"%s\", \"%s\") returned error %ld\n",
// (LPSTR) lpszValueName,
// (LPSTR) lpszBuf,
// (long) l));
goto end;
}
}
fRet = TRUE;
goto end;
#else // !USE_REGISTRY
LPSTR lpszKey;
LPSTR lpszProfileName;
if (!expand_key(dwKey, &lpszKey, &lpszProfileName)) goto end;
fRet = WritePrivateProfileString(lpszKey, lpszValueName,
lpszBuf, lpszProfileName);
goto end;
#endif // !USE_REGISTRY
BG_CHK(FALSE);
end:
return fRet;
}
void ProfileClose(ULONG_PTR dwKey)
{
#ifdef USE_REGISTRY
if (RegCloseKey((HKEY)dwKey)!=ERROR_SUCCESS)
{
//LOG((_WRN, "Couldn't close registry key:%lu\n\r",
// (unsigned long) dwKey));
}
#else
BG_CHK(LOWORD(dwKey)); GlobalDeleteAtom(LOWORD(dwKey));
BG_CHK(HIWORD(dwKey)); GlobalDeleteAtom(HIWORD(dwKey));
#endif
}
BOOL ProfileDeleteSection(DWORD dwProfileID, LPSTR lpszSection)
{
#ifdef USE_REGISTRY
char rgchKey[128];
LPSTR lpszPrefix= szKEYPREFIX "\\";
if (dwProfileID==OEM_BASEKEY) goto failure; // Can't delete this
if ((lstrlen(lpszPrefix)+lstrlen(lpszSection))>=sizeof(rgchKey))
goto failure;
lstrcpy(rgchKey, lpszPrefix);
lstrcat(rgchKey, lpszSection);
return (RegDeleteKey(DATABASE_KEY, rgchKey)==ERROR_SUCCESS);
failure:
return FALSE;
#else // !USE_REGISTRY
return WritePrivateProfileString(lpszSection, NULL, NULL, szINIFILE);
#endif // !USE_REGISTRY
}
BOOL
ProfileCopyTree(
DWORD dwProfileIDTo,
LPSTR lpszSectionTo,
DWORD dwProfileIDFr,
LPSTR lpszSectionFr)
{
BOOL fRet=TRUE;
char SecTo[200];
char SecFr[200];
//
// Since there is no CopyKeyWithAllSubkeys API, it is difficult to write generic tree-walking algorithm.
// We will hard-code the keys here.
//
// copy Fax key always
ProfileCopySection(dwProfileIDTo,
lpszSectionTo,
dwProfileIDFr,
lpszSectionFr,
TRUE);
// copy Fax/Class1 key if exists
sprintf(SecTo, "%s\\Class1", lpszSectionTo);
sprintf(SecFr, "%s\\Class1", lpszSectionFr);
ProfileCopySection(dwProfileIDTo,
SecTo,
dwProfileIDFr,
SecFr,
FALSE);
// copy Fax/Class1/AdaptiveAnswer key if exists
sprintf(SecTo, "%s\\Class1\\AdaptiveAnswer", lpszSectionTo);
sprintf(SecFr, "%s\\Class1\\AdaptiveAnswer", lpszSectionFr);
ProfileCopySection(dwProfileIDTo,
SecTo,
dwProfileIDFr,
SecFr,
FALSE);
// copy Fax/Class1/AdaptiveAnswer/Answer key if exists
sprintf(SecTo, "%s\\Class1\\AdaptiveAnswer\\AnswerCommand", lpszSectionTo);
sprintf(SecFr, "%s\\Class1\\AdaptiveAnswer\\AnswerCommand", lpszSectionFr);
ProfileCopySection(dwProfileIDTo,
SecTo,
dwProfileIDFr,
SecFr,
FALSE);
// copy Fax/Class2 key if exists
sprintf(SecTo, "%s\\Class2", lpszSectionTo);
sprintf(SecFr, "%s\\Class2", lpszSectionFr);
ProfileCopySection(dwProfileIDTo,
SecTo,
dwProfileIDFr,
SecFr,
FALSE);
// copy Fax/Class2/AdaptiveAnswer key if exists
sprintf(SecTo, "%s\\Class2\\AdaptiveAnswer", lpszSectionTo);
sprintf(SecFr, "%s\\Class2\\AdaptiveAnswer", lpszSectionFr);
ProfileCopySection(dwProfileIDTo,
SecTo,
dwProfileIDFr,
SecFr,
FALSE);
// copy Fax/Class2/AdaptiveAnswer/Answer key if exists
sprintf(SecTo, "%s\\Class2\\AdaptiveAnswer\\AnswerCommand", lpszSectionTo);
sprintf(SecFr, "%s\\Class2\\AdaptiveAnswer\\AnswerCommand", lpszSectionFr);
ProfileCopySection(dwProfileIDTo,
SecTo,
dwProfileIDFr,
SecFr,
FALSE);
// copy Fax/Class2_0 key if exists
sprintf(SecTo, "%s\\Class2_0", lpszSectionTo);
sprintf(SecFr, "%s\\Class2_0", lpszSectionFr);
ProfileCopySection(dwProfileIDTo,
SecTo,
dwProfileIDFr,
SecFr,
FALSE);
// copy Fax/Class2_0/AdaptiveAnswer key if exists
sprintf(SecTo, "%s\\Class2_0\\AdaptiveAnswer", lpszSectionTo);
sprintf(SecFr, "%s\\Class2_0\\AdaptiveAnswer", lpszSectionFr);
ProfileCopySection(dwProfileIDTo,
SecTo,
dwProfileIDFr,
SecFr,
FALSE);
// copy Fax/Class2/AdaptiveAnswer/Answer key if exists
sprintf(SecTo, "%s\\Class2_0\\AdaptiveAnswer\\AnswerCommand", lpszSectionTo);
sprintf(SecFr, "%s\\Class2_0\\AdaptiveAnswer\\AnswerCommand", lpszSectionFr);
ProfileCopySection(dwProfileIDTo,
SecTo,
dwProfileIDFr,
SecFr,
FALSE);
return fRet;
}
BOOL
ProfileCopySection(
DWORD dwProfileIDTo,
LPSTR lpszSectionTo,
DWORD dwProfileIDFr,
LPSTR lpszSectionFr,
BOOL fCreateAlways
)
{
BOOL fRet=FALSE;
DWORD iValue=0;
DWORD cbValue, cbData, dwType;
char rgchValue[60], rgchData[256];
HKEY hkFr;
HKEY hkTo;
hkFr = (HKEY) ProfileOpen(dwProfileIDFr, lpszSectionFr, fREG_READ);
if ( (!hkFr) && (!fCreateAlways) ) {
return fRet;
}
hkTo = (HKEY) ProfileOpen(dwProfileIDTo, lpszSectionTo,
fREG_CREATE |fREG_READ|fREG_WRITE);
if (!hkTo || !hkFr) goto end;
iValue=0;dwType=0;cbValue=sizeof(rgchValue);cbData=sizeof(rgchData);
while(RegEnumValue(hkFr, iValue, rgchValue, &cbValue,
NULL, &dwType, rgchData, &cbData)==ERROR_SUCCESS)
{
if (RegQueryValueEx(hkFr, rgchValue, NULL, &dwType, rgchData, &cbData)
==ERROR_SUCCESS)
{
if (RegSetValueEx(hkTo, rgchValue, 0, dwType, rgchData, cbData)
== ERROR_SUCCESS)
{
fRet=TRUE;
}
}
iValue++;dwType=0;cbValue=sizeof(rgchValue);cbData=sizeof(rgchData);
}
end:
if (hkTo) RegCloseKey(hkTo);
if (hkFr) RegCloseKey(hkFr);
return fRet;
}
DWORD ProfileGetData(ULONG_PTR dwKey, LPSTR lpszValueName,
LPBYTE lpbBuf , DWORD dwcbMax)
{
#ifndef USE_REGISTRY
return 0;
#else // USE_REGISTRY
DWORD dwType;
LONG l = RegQueryValueEx(
(HKEY) dwKey,
lpszValueName,
0,
&dwType,
lpbBuf,
&dwcbMax
);
if (l!=ERROR_SUCCESS)
{
//LOG((_ERR, "RegQueryValueEx returned error %ld\n", (long) l));
goto copy_default;
}
if (dwType != REG_BINARY)
{
goto copy_default;
}
return dwcbMax;
copy_default:
return 0;
#endif // USE_REGISTRY
}
BOOL ProfileWriteData(ULONG_PTR dwKey, LPSTR lpszValueName,
LPBYTE lpbBuf, DWORD dwcb)
{
#ifndef USE_REGISTRY
return 0;
#else // USE_REGISTRY
LONG l = ~(ERROR_SUCCESS);
if (!lpszValueName) goto end;
if (!lpbBuf)
{
// delete value...
l = RegDeleteValue((HKEY) dwKey, lpszValueName);
}
else
{
l = RegSetValueEx((HKEY) dwKey, lpszValueName, 0, REG_BINARY,
lpbBuf, dwcb);
}
end:
return (l==ERROR_SUCCESS);
#endif // USE_REGISTRY
}
#ifdef USE_REGISTRY
DWORD my_atoul(LPSTR lpsz)
{
unsigned i=8, c;
unsigned long ul=0;
while(i-- && (c=*lpsz++)) {
ul*=10;
switch(c) {
case '0': break;
case '1':ul+=1; break;
case '2':ul+=2; break;
case '3':ul+=3; break;
case '4':ul+=4; break;
case '5':ul+=5; break;
case '6':ul+=6; break;
case '7':ul+=7; break;
case '8':ul+=8; break;
case '9':ul+=9; break;
default: goto end;
}
}
end:
return ul;
}
#endif // USE_REGISTRY