446 lines
13 KiB
C
446 lines
13 KiB
C
//-----------------------------------------------------------------------//
|
|
//
|
|
// File: add.cpp
|
|
// Created: March 1997
|
|
// By: Martin Holladay (a-martih)
|
|
// Purpose: Registry Add (Write) Support for REG.CPP
|
|
// Modification History:
|
|
// March 1997 (a-martih):
|
|
// Copied from Query.cpp and modificd.
|
|
// October 1997 (martinho)
|
|
// Added additional termination character for MULTI_SZ strings.
|
|
// Added \0 delimiter between MULTI_SZ strings items
|
|
// April 1999 Zeyong Xu: re-design, revision -> version 2.0
|
|
//------------------------------------------------------------------------//
|
|
|
|
#include "stdafx.h"
|
|
#include "reg.h"
|
|
|
|
|
|
//-----------------------------------------------------------------------//
|
|
//
|
|
// AddRegistry()
|
|
//
|
|
//-----------------------------------------------------------------------//
|
|
|
|
LONG AddRegistry(PAPPVARS pAppVars, UINT argc, TCHAR *argv[])
|
|
{
|
|
LONG nResult;
|
|
HKEY hKey;
|
|
DWORD dwDisposition;
|
|
BYTE* byteData;
|
|
|
|
|
|
//
|
|
// Parse the cmd-line
|
|
//
|
|
nResult = ParseAddCmdLine(pAppVars, argc, argv);
|
|
if(nResult != ERROR_SUCCESS)
|
|
{
|
|
return nResult;
|
|
}
|
|
|
|
//
|
|
// Connect to the Remote Machine - if applicable
|
|
//
|
|
nResult = RegConnectMachine(pAppVars);
|
|
if (nResult != ERROR_SUCCESS)
|
|
{
|
|
return nResult;
|
|
}
|
|
|
|
//
|
|
// Create/Open the registry key
|
|
//
|
|
nResult = RegCreateKeyEx(pAppVars->hRootKey,
|
|
pAppVars->szSubKey,
|
|
0,
|
|
NULL,
|
|
REG_OPTION_NON_VOLATILE,
|
|
KEY_READ | KEY_WRITE,
|
|
NULL,
|
|
&hKey,
|
|
&dwDisposition);
|
|
|
|
if( nResult == ERROR_SUCCESS &&
|
|
pAppVars->szValueName )
|
|
{
|
|
// check value if existed
|
|
DWORD dwType;
|
|
DWORD dwLen = 1;
|
|
nResult = RegQueryValueEx(hKey,
|
|
pAppVars->szValueName,
|
|
NULL,
|
|
&dwType,
|
|
NULL,
|
|
&dwLen);
|
|
if(nResult == ERROR_SUCCESS)
|
|
{
|
|
// if exist
|
|
if(!Prompt(_T("Value %s exists, overwrite(Y/N)? "),
|
|
pAppVars->szValueName,
|
|
pAppVars->bForce) )
|
|
{
|
|
RegCloseKey(hKey);
|
|
return nResult;
|
|
}
|
|
}
|
|
|
|
nResult = ERROR_SUCCESS;
|
|
switch(pAppVars->dwRegDataType)
|
|
{
|
|
case REG_DWORD:
|
|
case REG_DWORD_BIG_ENDIAN:
|
|
// case REG_DWORD_LITTLE_ENDIAN:
|
|
//
|
|
// auto convert szValue (hex, octal, decimal format) to dwData
|
|
//
|
|
{
|
|
TCHAR* szStop = NULL;
|
|
DWORD dwData = _tcstoul(pAppVars->szValue, &szStop, 0);
|
|
if(_tcslen(szStop) > 0) // invalid data format
|
|
nResult = REG_STATUS_INVALIDPARAMS;
|
|
else
|
|
nResult = RegSetValueEx(hKey,
|
|
pAppVars->szValueName,
|
|
0,
|
|
pAppVars->dwRegDataType,
|
|
(BYTE*) &dwData,
|
|
sizeof(DWORD));
|
|
}
|
|
break;
|
|
|
|
case REG_BINARY:
|
|
{
|
|
|
|
TCHAR buff[3];
|
|
LONG onebyte;
|
|
LONG count = 0;
|
|
TCHAR* szStart;
|
|
TCHAR* szStop;
|
|
|
|
//
|
|
// Convert szValue (hex data string) to binary
|
|
//
|
|
dwLen = _tcslen(pAppVars->szValue);
|
|
byteData = (BYTE*) calloc(dwLen/2 + dwLen%2,
|
|
sizeof(BYTE));
|
|
if (!byteData) {
|
|
nResult = ERROR_NOT_ENOUGH_MEMORY;
|
|
goto Cleanup;
|
|
}
|
|
|
|
|
|
buff[2] = _T('\0');
|
|
|
|
count = 0;
|
|
szStart = pAppVars->szValue;
|
|
|
|
while(_tcslen(szStart) > 0)
|
|
{
|
|
buff[0] = *szStart;
|
|
szStart++;
|
|
if(_tcslen(szStart) > 0)
|
|
{
|
|
buff[1] = *szStart;
|
|
szStart++;
|
|
}
|
|
else
|
|
{
|
|
buff[1] = _T('0'); // if half byte, append a '0'
|
|
}
|
|
|
|
// hex format
|
|
onebyte = _tcstol(buff, &szStop, 16);
|
|
if(_tcslen(szStop) > 0) // invalid data format
|
|
{
|
|
nResult = REG_STATUS_INVALIDPARAMS;
|
|
break;
|
|
}
|
|
else
|
|
{
|
|
byteData[count] = (BYTE)(onebyte);
|
|
}
|
|
|
|
count++;
|
|
}
|
|
|
|
if(nResult == ERROR_SUCCESS)
|
|
{
|
|
nResult = RegSetValueEx(hKey,
|
|
pAppVars->szValueName,
|
|
0,
|
|
pAppVars->dwRegDataType,
|
|
byteData,
|
|
count);
|
|
}
|
|
|
|
if(byteData)
|
|
free(byteData);
|
|
}
|
|
break;
|
|
|
|
case REG_SZ:
|
|
case REG_EXPAND_SZ:
|
|
case REG_NONE:
|
|
dwLen = (_tcslen(pAppVars->szValue) + 1) * sizeof(TCHAR);
|
|
nResult = RegSetValueEx(hKey,
|
|
pAppVars->szValueName,
|
|
0,
|
|
pAppVars->dwRegDataType,
|
|
(BYTE*) pAppVars->szValue,
|
|
dwLen);
|
|
break;
|
|
|
|
case REG_MULTI_SZ:
|
|
{
|
|
BOOL bErrorString = FALSE;
|
|
DWORD dwLengthOfSeparator = _tcslen(pAppVars->szSeparator);
|
|
BOOL bTrailing = FALSE;
|
|
TCHAR* szData;
|
|
TCHAR* pStart;
|
|
TCHAR* pEnd;
|
|
TCHAR* pString;
|
|
|
|
|
|
//
|
|
// Replace separator("\0") with '\0' for MULTI_SZ,
|
|
// "\0" uses to separate string by default,
|
|
// if two separators("\0\0"), error
|
|
//
|
|
dwLen = _tcslen(pAppVars->szValue);
|
|
// calloc() initializes all char to 0
|
|
szData = (TCHAR*) calloc(dwLen + 2, sizeof(TCHAR));
|
|
pStart = pAppVars->szValue;
|
|
pString = szData;
|
|
|
|
if (!szData) {
|
|
nResult = ERROR_NOT_ENOUGH_MEMORY;
|
|
goto Cleanup;
|
|
}
|
|
|
|
while(_tcslen(pStart) > 0)
|
|
{
|
|
pEnd = _tcsstr(pStart, pAppVars->szSeparator);
|
|
if(pEnd)
|
|
{
|
|
/*
|
|
**** MODIFIED BY V-SMGUM ****
|
|
|
|
//two separators("\0\0") inside string
|
|
if( pEnd == pStart ||
|
|
//one separator("\0") in end of string
|
|
_tcslen(pEnd) == dwLengthOfSeparator)
|
|
{
|
|
bErrorString = TRUE;
|
|
break;
|
|
}
|
|
*pEnd = 0;
|
|
*/
|
|
|
|
//
|
|
// MODIFIED BY V-SMGUM
|
|
// THIS IS TO REMOVE THE TRAILING SEPERATOR EVEN IF IT IS SPECIFIED
|
|
//
|
|
|
|
// specifying two seperators in the data is error
|
|
bTrailing = FALSE;
|
|
if ( pEnd == pStart )
|
|
{
|
|
bErrorString = TRUE;
|
|
break;
|
|
}
|
|
else if ( _tcslen( pEnd ) == dwLengthOfSeparator )
|
|
{
|
|
// set the flag
|
|
bTrailing = TRUE;
|
|
}
|
|
*pEnd = 0;
|
|
}
|
|
|
|
// do the concat only if start is having valid buffer
|
|
_tcscat(pString, pStart);
|
|
pString += _tcslen(pString) + 1;
|
|
|
|
if( pEnd && bTrailing == FALSE )
|
|
pStart = pEnd + dwLengthOfSeparator;
|
|
else
|
|
break;
|
|
}
|
|
|
|
// empty
|
|
if(_tcsicmp(pAppVars->szValue, pAppVars->szSeparator) == 0)
|
|
{
|
|
pString = szData + 2;
|
|
bErrorString = FALSE;
|
|
}
|
|
else
|
|
pString += 1; // double null terminated string
|
|
|
|
if(bErrorString)
|
|
{
|
|
nResult = REG_STATUS_INVALIDPARAMS;
|
|
}
|
|
else
|
|
{
|
|
DWORD dwByteToWrite = (DWORD)((pString - szData) * sizeof(TCHAR));
|
|
|
|
nResult = RegSetValueEx(hKey,
|
|
pAppVars->szValueName,
|
|
0,
|
|
pAppVars->dwRegDataType,
|
|
(BYTE*) szData,
|
|
dwByteToWrite);
|
|
}
|
|
|
|
if(szData)
|
|
free(szData);
|
|
}
|
|
break;
|
|
|
|
default:
|
|
nResult = REG_STATUS_INVALIDPARAMS;
|
|
break;
|
|
}
|
|
|
|
RegCloseKey(hKey);
|
|
}
|
|
|
|
Cleanup:
|
|
return nResult;
|
|
}
|
|
|
|
//------------------------------------------------------------------------//
|
|
//
|
|
// ParseAddCmdLine()
|
|
//
|
|
//------------------------------------------------------------------------//
|
|
|
|
REG_STATUS ParseAddCmdLine(PAPPVARS pAppVars, UINT argc, TCHAR *argv[])
|
|
{
|
|
REG_STATUS nResult = ERROR_SUCCESS;
|
|
UINT i;
|
|
BOOL bHasType = FALSE;
|
|
|
|
if(argc < 3)
|
|
{
|
|
return REG_STATUS_TOFEWPARAMS;
|
|
}
|
|
|
|
// Machine Name and Registry key
|
|
//
|
|
nResult = BreakDownKeyString(argv[2], pAppVars);
|
|
if(nResult != ERROR_SUCCESS)
|
|
return nResult;
|
|
|
|
// parsing
|
|
for(i=3; i<argc; i++)
|
|
{
|
|
if(!_tcsicmp(argv[i], _T("/v")))
|
|
{
|
|
if(pAppVars->szValueName)
|
|
return REG_STATUS_INVALIDPARAMS;
|
|
|
|
i++;
|
|
if(i<argc)
|
|
{
|
|
pAppVars->szValueName = (TCHAR*) calloc(_tcslen(argv[i]) + 1,
|
|
sizeof(TCHAR));
|
|
if (!pAppVars->szValueName) {
|
|
return ERROR_NOT_ENOUGH_MEMORY;
|
|
}
|
|
_tcscpy(pAppVars->szValueName, argv[i]);
|
|
}
|
|
else
|
|
return REG_STATUS_TOFEWPARAMS;
|
|
}
|
|
else if(!_tcsicmp(argv[i], _T("/ve")))
|
|
{
|
|
if(pAppVars->szValueName)
|
|
return REG_STATUS_INVALIDPARAMS;
|
|
|
|
pAppVars->szValueName = (TCHAR*) calloc(1, sizeof(TCHAR));
|
|
if (!pAppVars->szValueName) {
|
|
return ERROR_NOT_ENOUGH_MEMORY;
|
|
}
|
|
}
|
|
else if(!_tcsicmp(argv[i], _T("/t")))
|
|
{
|
|
i++;
|
|
if(i<argc)
|
|
{
|
|
pAppVars->dwRegDataType = IsRegDataType(argv[i]);
|
|
if(pAppVars->dwRegDataType == (DWORD)-1)
|
|
{
|
|
return REG_STATUS_INVALIDPARAMS;
|
|
}
|
|
|
|
bHasType = TRUE;
|
|
}
|
|
else
|
|
return REG_STATUS_TOFEWPARAMS;
|
|
}
|
|
else if(!_tcsicmp(argv[i], _T("/s")))
|
|
{
|
|
if(pAppVars->dwRegDataType != REG_MULTI_SZ)
|
|
return REG_STATUS_INVALIDPARAMS;
|
|
|
|
i++;
|
|
if(i<argc)
|
|
{
|
|
if(_tcslen(argv[i]) == 1)
|
|
{
|
|
_tcscpy(pAppVars->szSeparator, argv[i]);
|
|
}
|
|
else
|
|
return REG_STATUS_INVALIDPARAMS;
|
|
}
|
|
else
|
|
return REG_STATUS_TOFEWPARAMS;
|
|
}
|
|
else if(!_tcsicmp(argv[i], _T("/d")))
|
|
{
|
|
if(pAppVars->szValue)
|
|
return REG_STATUS_INVALIDPARAMS;
|
|
|
|
i++;
|
|
if(i<argc)
|
|
{
|
|
pAppVars->szValue = (TCHAR*) calloc(_tcslen(argv[i]) + 1,
|
|
sizeof(TCHAR));
|
|
if (!pAppVars->szValue) {
|
|
return ERROR_NOT_ENOUGH_MEMORY;
|
|
}
|
|
_tcscpy(pAppVars->szValue, argv[i]);
|
|
}
|
|
else
|
|
return REG_STATUS_TOFEWPARAMS;
|
|
}
|
|
else if(!_tcsicmp(argv[i], _T("/f")))
|
|
{
|
|
pAppVars->bForce = TRUE;
|
|
}
|
|
else
|
|
return REG_STATUS_TOMANYPARAMS;
|
|
}
|
|
|
|
// if no value, set to empty value data
|
|
if(pAppVars->szValueName && !pAppVars->szValue)
|
|
{
|
|
pAppVars->szValue = (TCHAR*) calloc(1, sizeof(TCHAR));
|
|
if (!pAppVars->szValue) {
|
|
return ERROR_NOT_ENOUGH_MEMORY;
|
|
}
|
|
*(pAppVars->szValue) = 0;
|
|
}
|
|
else if( !pAppVars->szValueName &&
|
|
(bHasType || pAppVars->szValue) )
|
|
{
|
|
return REG_STATUS_INVALIDPARAMS;
|
|
}
|
|
|
|
return ERROR_SUCCESS;
|
|
}
|
|
|
|
|