|
|
/***************************************************************************
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
|