#include "Helpers.h"
typedef union {
TCHAR chr;
int i;
unsigned u;
long l;
unsigned long ul;
double dbl;
float flt;
LPTSTR str;
} VA_VALUE;
/*
// check if SHLOBJ.H included
#include <ShlObj.h>
// Macros for interface casts
#define IID_PPV_ARG(IType, ppType) IID_##IType, (void**)(ppType)
#define ILSkip(pidl, cb) ((LPITEMIDLIST)(((BYTE*)(pidl))+cb))
#define ILNext(pidl) ILSkip(pidl, (pidl)->mkid.cb)
//#endif // _SHLOBJ_H_
*/
#define STRLENBODY(str) { \
DWORD i=0; \
while(str && str[i]) i++; \
return i; \
}
DWORD StrLen(LPCWSTR str) STRLENBODY(str)
DWORD StrLen(LPCSTR str) STRLENBODY(str)
LPSTR StrDup(LPCSTR str)
{
LPSTR dup=new CHAR[StrLen(str)+1];
DWORD i=0;
while(dup && (dup[i]=str[i])!=0) i++;
return dup;
}
LPWSTR StrDup(LPCWSTR str)
{
LPWSTR dup=new WCHAR[StrLen(str)+1];
DWORD i=0;
while(dup && (dup[i]=str[i])!=0) i++;
return dup;
}
LPSTR StrCopy(LPSTR dst,LPCSTR src)
{
while((*(dst++)=*(src++))!=0);
return (dst-1);
}
LPWSTR StrCopy(LPWSTR dst,LPCWSTR src)
{
while((*(dst++)=*(src++))!=0);
return (dst-1);
}
/*
void StrCopy(LPSTR dst, LPCSTR src)
{
__asm{
MOV ESI, src
MOV EDI, dst
XOR EAX,EAX
CLD
StrCopyALoop:
MOVS byte ptr [EDI],[ESI]
CMP [ESI],AL
JNE StrCopyALoop
MOV [EDI],AX
}
}
void StrCopy(LPWSTR dst, LPCWSTR src)
{
__asm{
MOV ESI, src
MOV EDI, dst
XOR EAX,EAX
CLD
StrCopyWLoop:
MOVS word ptr [EDI],[ESI]
CMP [ESI],AX
JNE StrCopyWLoop
MOV [EDI],AX
}
}
*/
LPSTR StrNCopy(LPSTR dst,LPCSTR src,DWORD ln)
{
while((*(dst++)=*(src++))!=0 && (ln--));
return dst;
}
LPWSTR StrNCopy(LPWSTR dst,LPCWSTR src,DWORD ln)
{
while((*(dst++)=*(src++))!=0 && (ln--));
return dst;
}
/*
StrNCopy(LPSTR dst,LPCSTR src,DWORD ln)
{
__asm{
MOV ESI, src
MOV EDI, dst
MOV ECX, ln
INC ECX
XOR AL,AL
CLD
StrNCopyALoop:
MOVS byte ptr [EDI],[ESI]
CMP [ESI],AL
LOOPNZ StrNCopyALoop
MOV [EDI],AL
}
}
void StrNCopy(LPWSTR dst,LPCWSTR src,DWORD ln)
{
__asm{
MOV ESI, src
MOV EDI, dst
MOV ECX, ln
INC ECX
CLD
REPNZ MOVS word ptr [EDI],[ESI]
}
}
*/
int StrNCmp(LPCSTR str1, LPCSTR str2, DWORD len)
{
int ret = 0;
while(len-- && (ret=(*str1-*str2))==0 && *str1!=0 && *str2!=0) {
str1++;
str2++;
}
return ret;
}
int StrNCmp(LPCWSTR str1, LPCWSTR str2, DWORD len)
{
int ret = 0;
while(len-- && (ret=(*str1-*str2))==0 && *str1!=0 && *str2!=0) {
str1++;
str2++;
}
return ret;
}
int StrCmp(LPCSTR str1, LPCSTR str2)
{
int ret;
while((ret=(*str1-*str2))==0 && *str1!=0 && *str2!=0) {
str1++;
str2++;
}
return ret;
}
int StrCmp(LPCWSTR str1, LPCWSTR str2)
{
int ret;
while((ret=(*str1-*str2))==0 && *str1!=0 && *str2!=0) {
str1++;
str2++;
}
return ret;
}
LPTSTR StrChar(LPCTSTR str,TCHAR chr)
{
while(*str!=chr) if (*(str++)==0) return NULL;
return (LPTSTR)str;
}
LPTSTR StrRChar(LPCTSTR str,TCHAR chr)
{
LPTSTR lpRet=NULL;
do {
if (*str==chr) lpRet=(LPTSTR)str;
} while(*(str++)!=0);
return lpRet;
}
BOOL CreateDirRecursive(LPCTSTR lpDir)
{
if (CreateDirectory(lpDir, NULL)) return TRUE;
// Creation failed!!! it seems to be many non-existing paths with each other
if (GetLastError() == ERROR_PATH_NOT_FOUND) {
LPTSTR lpTemp =StrChar(lpDir,'\\');
BOOL ret;
if (lpTemp) {
*lpTemp = 0;
ret=CreateDirRecursive(lpDir);
*lpTemp = '\\';
if (ret) {
ret=CreateDirectory(lpDir, NULL);
if (ret || GetLastError()==ERROR_ALREADY_EXISTS) {
return TRUE;
}
}
}
}
return FALSE;
}
int StrFormat(LPTSTR out, LPCTSTR format, ...)
{
va_list arg;
VA_VALUE par;
LPTSTR tout=out;
LPCTSTR tfmt = format;
va_start(arg, format);
while (*tfmt != 0) {
switch (*tfmt) {
case '%':
switch (tfmt[1]) {
case 'd': // decimal
{
long div = 1000000000, factor;
par.i = va_arg(arg, int);
do {
factor = par.i / div;
if (factor<0) factor= -factor;
if (factor) {
*(tout++) = (factor /100) + '0';
*(tout++) = (factor /10)%10 + '0';
*(tout++) = (factor % 10) + '0';
*(tout++) = ' ';
// tmp = _itoa(factor, tout, 10);
}
par.i %= div;
div /=1000;
} while (div>0);
}
break;
case 's': // string
par.str = va_arg(arg, LPTSTR);
tout = StrCopy(tout,par.str);
break;
default:
DebugBreak();
/*---------------------------------------
case 'x': // hexadecimal
par.i = va_arg(arg, int);
break;
case 'f': // float
par.flt = va_arg(arg, float);
break;
case 'c': // char
par.chr = va_arg(arg, TCHAR);
break;
*/
}
tfmt+=2;
break;
default:
*tout = *tfmt;
tout++;
tfmt++;
}
}
va_end(arg);
return (tout - out);
}
/*
//#ifdef _SHLOBJ_H_
// Retrieves the UIObject interface for the specified full PIDL
STDAPI SHGetUIObjectFromFullPIDL(LPCITEMIDLIST pidl, HWND hwnd, REFIID riid, void **ppv)
{
LPCITEMIDLIST pidlChild;
IShellFolder* psf;
*ppv = NULL;
HRESULT hr = SHBindToParent(pidl, IID_PPV_ARG(IShellFolder, &psf), &pidlChild);
//HRESULT hr = SHBindToParent(pidl, IID_IShellLink, (void**)&psf, &pidlChild);
if (SUCCEEDED(hr))
{
hr = psf->GetUIObjectOf(hwnd, 1, &pidlChild, riid, NULL, ppv);
psf->Release();
}
return hr;
}
HRESULT SHILClone(LPCITEMIDLIST pidl, LPITEMIDLIST *ppidl)
{
DWORD cbTotal = 0;
if (pidl)
{
cbTotal += sizeof(pidl->mkid.cb);
while (pidl->mkid.cb)
{
cbTotal += pidl->mkid.cb;
pidl = ILNext(pidl);
}
}
*ppidl = (LPITEMIDLIST)CoTaskMemAlloc(cbTotal);
if (*ppidl)
CopyMemory(*ppidl, pidl, cbTotal);
return *ppidl ? S_OK: E_OUTOFMEMORY;
}
// Get the target PIDL for a folder PIDL. This deals with cases where a folder
// is an alias to a real folder, folder shortcuts, etc.
STDAPI SHGetTargetFolderIDList(LPCITEMIDLIST pidlFolder, LPITEMIDLIST *ppidl)
{
IShellLink *psl;
*ppidl = NULL;
HRESULT hr = SHGetUIObjectFromFullPIDL(pidlFolder, NULL, IID_PPV_ARG(IShellLink, &psl));
//HRESULT hr = SHGetUIObjectFromFullPIDL(pidlFolder, NULL, IID_IShellLink, (void**)&psl);
if (SUCCEEDED(hr))
{
hr = psl->GetIDList(ppidl);
psl->Release();
}
// It's not a folder shortcut so get the PIDL normally.
if (FAILED(hr))
hr = SHILClone(pidlFolder, ppidl);
return hr;
}
// Get the target folder for a folder PIDL. This deals with cases where a folder
// is an alias to a real folder, folder shortcuts, the My Documents folder, etc.
STDAPI SHGetTargetFolderPath(LPCITEMIDLIST pidlFolder, LPWSTR pszPath, UINT cchPath)
{
LPITEMIDLIST pidlTarget;
*pszPath = 0;
HRESULT hr = SHGetTargetFolderIDList(pidlFolder, &pidlTarget);
if (SUCCEEDED(hr))
{
SHGetPathFromIDListW(pidlTarget, pszPath); // Make sure it is a path
CoTaskMemFree(pidlTarget);
}
return *pszPath ? S_OK : E_FAIL;
}
//#endif // _SHLOBJ_H_
*/