LONG CRegKey::SetValue(LPCWSTR lpValueName,LPCWSTR strData,DWORD cbDataAsChars,DWORD dwType)
{
	if (IsUnicodeSystem())
	{
		if (dwType==REG_SZ || dwType==REG_EXPAND_SZ || dwType==REG_MULTI_SZ)
			cbDataAsChars*=2;
		return ::RegSetValueExW(m_hKey,lpValueName,0,dwType,(CONST BYTE*)strData,cbDataAsChars);
	}
	else
	{
		switch (dwType)
		{
		case REG_SZ:
		case REG_EXPAND_SZ:
			{
				char* lpDataA=alloccopyWtoA((LPCWSTR)strData,cbDataAsChars);
				LONG lRet=::RegSetValueExA(m_hKey,W2A(lpValueName),0,dwType,(CONST BYTE*)lpDataA,cbDataAsChars);
				delete[] lpDataA;
				return lRet;
			}
		case REG_MULTI_SZ:
			{
				SIZE_T i;
				for (i=0;(((LPCWSTR)strData)[i]!='\0' || ((LPCWSTR)strData)[i+1]!='\0') && i<cbDataAsChars;i++);
				char* pDataA=new char[i+2];
				ULONG_PTR ind=0;			
				while (((LPCWSTR)strData)[ind]!='\0' && ind<cbDataAsChars)
				{
					SIZE_T nlen=wcslen(((LPCWSTR)strData)+ind);
					MemCopyWtoA(pDataA+ind,((LPCWSTR)strData)+ind,nlen);
					ind+=nlen;
					pDataA[ind++]='\0';
				}
				pDataA[ind]='\0';
				LONG lRet=::RegSetValueExA(m_hKey,W2A(lpValueName),0,dwType,(CONST BYTE*)pDataA,cbDataAsChars);
				delete[] pDataA;
				return lRet;
			}
		default:
			return ::RegSetValueExA(m_hKey,W2A(lpValueName),0,dwType,(CONST BYTE*)strData,cbDataAsChars);
		}
	}
}
BYTE* dataparser(LPCWSTR pStr,DWORD dwStrLen,MALLOC_FUNC pMalloc,DWORD* pdwDataLength)
{
	if (pStr[0]==L'\0')
		return NULL;
	
	if (_1stcontain2nd(pStr,L"int:"))
	{
		pStr+=4;
		BYTE* pRet=(BYTE*)pMalloc(4);
		*((DWORD*)pRet)=DWORD(_readnum(10,pStr));
		if (pdwDataLength!=NULL)
			*pdwDataLength=4;
		return pRet;
	}
	else if (_1stcontain2nd(pStr,L"dword"))
	{
		pStr+=5;
		int base=_getbase(pStr);
		if (*pStr!=':')
			return NULL;
		pStr++;
		BYTE* pRet=(BYTE*)pMalloc(4);
		*((DWORD*)pRet)=DWORD(_readnum(base,pStr));
		if (pdwDataLength!=NULL)
			*pdwDataLength=4;
		return pRet;
	}
	else if (_1stcontain2nd(pStr,L"word"))
	{
		pStr+=4;		
		int base=_getbase(pStr);
		if (*pStr!=':')
			return NULL;
		pStr++;
		BYTE* pRet=(BYTE*)pMalloc(2);
		*((WORD*)pRet)=WORD(_readnum(base,pStr));
		if (pdwDataLength!=NULL)
			*pdwDataLength=2;
		return pRet;
	}
	else if (_1stcontain2nd(pStr,L"byte"))
	{
		pStr+=4;		
		int base=_getbase(pStr);
		if (*pStr!=':')
			return NULL;
		pStr++;
		BYTE* pRet=(BYTE*)pMalloc(2);
		*pRet=BYTE(_readnum(base,pStr));
		if (pdwDataLength!=NULL)
			*pdwDataLength=1;
		return pRet;
	}
	else if (_1stcontain2nd(pStr,L"hex:") || _1stcontain2nd(pStr,L"bin:"))
	{
		pStr+=4;
		int i=0;
		
		// Calculating reqiured size
		for (LPCWSTR pStr2=pStr;*pStr2!='\0';i++)
		{
			if (!((*pStr2>='0' && *pStr2<='9') || 
				(*pStr2>='a' && *pStr2<='f') ||
				(*pStr2>='A' && *pStr2<='F')))
				break;
				
			pStr2++;

			if ((*pStr2>='0' && *pStr2<='9') || 
				(*pStr2>='a' && *pStr2<='f') ||
				(*pStr2>='A' && *pStr2<='F'))
				pStr2++;

			for (;*pStr2==' ';pStr2++);
		}

		if (i==0)
			return NULL;
			
		BYTE* pRet=(BYTE*)pMalloc(max(i,2));

		for (i=0;*pStr!='\0';i++)
		{
			if (*pStr>='0' && *pStr<='9')
				pRet[i]=*pStr-'0';
			else if (*pStr>='a' && *pStr<='f')
				pRet[i]=*pStr-'a'+0xa;
			else if (*pStr>='A' && *pStr<='F')
				pRet[i]=*pStr-'A'+0xa;
			else
				break;

			pStr++;

			if (*pStr>='0' && *pStr<='9')
			{
				pRet[i]<<=4;
				pRet[i]+=*pStr-'0';
				pStr++;
			}
			else if (*pStr>='a' && *pStr<='f')
			{
				pRet[i]<<=4;
				pRet[i]+=*pStr-'a'+0xa;
				pStr++;
			}
			else if (*pStr>='A' && *pStr<='F')
			{
				pRet[i]<<=4;
				pRet[i]+=*pStr-'A'+0xa;
				pStr++;
			}

			for (;*pStr==' ';pStr++);
		}
		if (pdwDataLength!=NULL)
			*pdwDataLength=i;
		return pRet;
	}
	else if (_1stcontain2nd(pStr,L"str:"))
	{
		dwStrLen-=4;
		pStr+=4;
		if (int(dwStrLen)<=0)
			return NULL;

		WCHAR* pUnicode;
		int len=_readstringW(pUnicode,pStr,dwStrLen,malloc);

		// Get Length
		len=WideCharToMultiByte(CP_ACP,0,pUnicode,len,NULL,0,NULL,NULL);
		char* pRet=(char*)pMalloc(len+1);		
		len=WideCharToMultiByte(CP_ACP,0,pUnicode,len,pRet,len+1,NULL,NULL);

		free(pUnicode);
		
		if (pdwDataLength!=NULL)
			*pdwDataLength=len;
		return (BYTE*)pRet;
	}
	else if (_1stcontain2nd(pStr,L"oem:"))
	{
		dwStrLen-=4;
		pStr+=4;
		if (int(dwStrLen)<=0)
			return NULL;
		
		WCHAR* pUnicode;
		int len=_readstringW(pUnicode,pStr,dwStrLen,malloc);

		// Get Length
		len=WideCharToMultiByte(CP_OEMCP,0,pUnicode,len,NULL,0,NULL,NULL);
		char* pRet=(char*)pMalloc(len+1);		
		len=WideCharToMultiByte(CP_OEMCP,0,pUnicode,len,pRet,len+1,NULL,NULL);

		free(pUnicode);
		
		if (pdwDataLength!=NULL)
			*pdwDataLength=len;
		return (BYTE*)pRet;
	}
	else if (_1stcontain2nd(pStr,L"wstr:") || _1stcontain2nd(pStr,L"uni:") || _1stcontain2nd(pStr,L"utf16:"))
	{
		for (pStr+=3,dwStrLen-=3;*pStr!=':';pStr++,dwStrLen--);
		pStr++;dwStrLen--;

		if (int(dwStrLen)<=0)
			return NULL;
	
		WCHAR* pRet;
		int len=_readstringW(pRet,pStr,dwStrLen,pMalloc);
		
		if (pdwDataLength!=NULL)
			*pdwDataLength=len*2;
		return (BYTE*)pRet;
	}
	else if (_1stcontain2nd(pStr,L"utf8:"))
	{
		dwStrLen-=5;
		pStr+=5;
		if (int(dwStrLen)<=0)
			return NULL;
		
		WCHAR* pUnicode;
		int len=_readstringW(pUnicode,pStr,dwStrLen,malloc);

		// Get Length
		char* pRet=(char*)pMalloc((len+1)*2);		
		len=WideCharToMultiByte(CP_UTF8,0,pUnicode,len,pRet,(len+1)*2,NULL,NULL);

		free(pUnicode);
		
		if (pdwDataLength!=NULL)
			*pdwDataLength=len;
		return (BYTE*)pRet;
	}
	else if (_1stcontain2nd(pStr,L"utf7:"))
	{
		dwStrLen-=5;
		pStr+=5;
		if (int(dwStrLen)<=0)
			return NULL;
		
		WCHAR* pUnicode;
		int len=_readstringW(pUnicode,pStr,dwStrLen,malloc);

		// Get Length
		char* pRet=(char*)pMalloc((len+1)*5);		
		len=WideCharToMultiByte(CP_UTF7,0,pUnicode,len,pRet,(len+1)*5,NULL,NULL);

		free(pUnicode);
		
		if (pdwDataLength!=NULL)
			*pdwDataLength=len;
		return (BYTE*)pRet;
	}
	else
	{
		if (int(dwStrLen)<=0)
			return NULL;
		
		if (pdwDataLength!=NULL)
			*pdwDataLength=dwStrLen;

		int nAllocLen=LenWtoA(pStr,dwStrLen);
		char* pNew=(char*)pMalloc(nAllocLen+1);
		MemCopyWtoA(pNew,nAllocLen+1,pStr,dwStrLen);
		pNew[nAllocLen]='\0';
		return (BYTE*)pNew;
	}
}