/************************************
REVISION LOG ENTRY
Revision By: Zhefu Zhang
Contact : codetiger@hotmail.com
Revised on 2/13/2004 10:11:25 AM
Comment: it is part of the code sample of
http://www.codeguru.com/misc/RunUser.html
************************************/
#include "StdAfx.h"
#include "z.h"
//Able Convert Part Str->WStr //return in WCHARs
//Can handle any size string, but user must VirtualFree the
//return pointer
LPWSTR _A2Wex(LPSTR szMultiByte, DWORD dwSize, DWORD& dwRetSize)
{
if(szMultiByte == NULL || (dwSize == -1 && ::strlen(szMultiByte) == 0))
{ dwRetSize = 0; return NULL; }
int nLen = MultiByteToWideChar(CP_ACP, 0,szMultiByte, dwSize, NULL, NULL);
LPWSTR pInside = (LPWSTR)::VirtualAlloc(NULL, nLen*sizeof(WCHAR),MEM_COMMIT, PAGE_READWRITE);
if(pInside == NULL)
{ dwRetSize = 0; return NULL;}
//dwRetSize in WCHARs, include null if szMultiByte nulled ended
dwRetSize = MultiByteToWideChar(CP_ACP, 0, szMultiByte, dwSize, pInside, 8096);
if(dwSize == -1)
dwRetSize--;
else
pInside[dwRetSize] = WCHAR('\0');
return pInside;
}
//return BYTEs,
//dwSize in WCHAR
//Can handle any size string, but user must VirtualFree the
//return pointer
LPSTR _W2Aex(LPWSTR szUnicode, DWORD dwSize, DWORD& dwRetSize)
{
if(szUnicode == NULL || (dwSize == -1 && ::wcslen(szUnicode) == 0))
{ dwRetSize = 0; return NULL; }
int nLen = WideCharToMultiByte(CP_ACP, 0,szUnicode, dwSize, NULL, 0, NULL, FALSE);
LPSTR pInside = (LPSTR)::VirtualAlloc(NULL, nLen*sizeof(char),MEM_COMMIT, PAGE_READWRITE);
if(pInside == NULL) { dwRetSize = 0; return NULL; }
//Ret: in BYTEs, The number includes the byte for the null terminator. if szUnicode null ended
dwRetSize = WideCharToMultiByte(CP_ACP, 0, szUnicode, dwSize, pInside, nLen, NULL, FALSE);
if(dwSize == -1) //dwRetSize include null, szInternalBuffer null ended
dwRetSize--;
else
pInside[dwRetSize] = char('\0');
return pInside;
}
//Always Convert Whole String
LPWSTR myA2W(LPSTR szMultiByte, DWORD& dwSize)
{
static WCHAR szInternalBuffer[8096];
if(szMultiByte == NULL || ::strlen(szMultiByte) == 0)
{ dwSize = 0; return NULL; }
int nLen = MultiByteToWideChar(CP_ACP, 0,szMultiByte, -1, NULL, NULL);
if(nLen > 8096) { dwSize = 0; return NULL; }
MultiByteToWideChar(CP_ACP, 0, szMultiByte, -1, szInternalBuffer, nLen);
return szInternalBuffer;
}
//Able Convert Part Str->WStr
//return in WCHARs
LPWSTR _A2W(LPSTR szMultiByte, DWORD dwSize, DWORD& dwRetSize)
{
static WCHAR szInternalBuffer[8096];
if(szMultiByte == NULL || (dwSize == -1 && ::strlen(szMultiByte) == 0))
{ dwRetSize = 0; return NULL; }
int nLen = MultiByteToWideChar(CP_ACP, 0,szMultiByte, dwSize, NULL, NULL);
if(nLen > 8096) { dwRetSize = 0; return NULL; }
//dwRetSize in WCHARs, include null if szMultiByte nulled ended
dwRetSize = MultiByteToWideChar(CP_ACP, 0, szMultiByte, dwSize, szInternalBuffer, 8096);
if(dwSize == -1)
dwRetSize--;
else
szInternalBuffer[dwRetSize] = WCHAR('\0');
return szInternalBuffer;
}
//return BYTEs,
//dwSize in WCHAR
LPSTR _W2A(LPWSTR szUnicode, DWORD dwSize, DWORD& dwRetSize)
{
static char szInternalBuffer[8096];
if(szUnicode == NULL || (dwSize == -1 && ::wcslen(szUnicode) == 0))
{ dwRetSize = 0; return NULL; }
int nLen = WideCharToMultiByte(CP_ACP, 0,szUnicode, dwSize, NULL, 0, NULL, FALSE);
if(nLen > 8096) { dwRetSize = 0; return NULL; }
//Ret: in BYTEs, The number includes the byte for the null terminator. if szUnicode null ended
dwRetSize = WideCharToMultiByte(CP_ACP, 0, szUnicode, dwSize, szInternalBuffer, nLen, NULL, FALSE);
if(dwSize == -1) //dwRetSize include null, szInternalBuffer null ended
dwRetSize--;
else
szInternalBuffer[dwRetSize] = char('\0');
return szInternalBuffer;
}
//Full Path is limited 248 long
BOOL ZMakeSureDirectoryPathExistsA(LPCSTR szFullPath)
{
CString strPath = szFullPath;
//PopMsg(_T("ZMakeA - ") + strPath);
if(strPath.GetLength() < 3) return FALSE;
if(strPath.Mid(1,2) != _T(":\\")) return FALSE;
if(strPath.Right(1) != _T("\\")) strPath += _T("\\");
/*C:\r\*/
int pos = strPath.Find(_T("\\"), 3);
while(pos != -1 && pos <= strPath.GetLength()-1)
{
CString strPartPath = strPath.Left(pos);
DWORD dwFileAttr = ::GetFileAttributes(strPartPath);
if(dwFileAttr == FILE_ATTRIBUTE_DIRECTORY)
{}
else
{
BOOL b = ::CreateDirectory(strPartPath, NULL);
if(!b) return FALSE;
}
pos = strPath.Find(_T("\\"), pos + 1);
}
return TRUE;
}
BOOL ZMakeSureDirectoryPathExistsW(LPCWSTR szFullPath)
{
CString strPath = szFullPath;
//PopMsg(_T("ZMakeW - ") + strPath);
if(strPath.GetLength() < 3) return FALSE;
if(strPath.Mid(1,2) != _T(":\\") &&
strPath.Left(4) != _T("\\\\?\\"))
return FALSE;
if(strPath.Right(1) != _T("\\")) strPath += _T("\\");
/*C:\r\ \\?\*/
int pos;
if(strPath.Left(4) == _T("\\\\?\\"))
pos = strPath.Find(_T("\\"), 7);
else
pos = strPath.Find(_T("\\"), 3);
while(pos != -1 && pos <= strPath.GetLength()-1)
{
CString strPartPath = strPath.Left(pos);
DWORD dwFileAttr = ::GetFileAttributes(strPartPath);
if(dwFileAttr == FILE_ATTRIBUTE_DIRECTORY)
{}
else
{
BOOL b = ::CreateDirectory(strPartPath, NULL);
if(!b) return FALSE;
}
pos = strPath.Find(_T("\\"), pos + 1);
}
return TRUE;
}
//Log Process & Thread Info
BOOL WriteProcessLog(LPCTSTR szFilename, LPCTSTR szRoutine, DWORD dwPID, DWORD dwTID)
{
#ifndef _DEBUG
return TRUE;
#endif
static CZCriticalSection cs;
cs.EnterCriticalSection();
TCHAR chFilename[_MAX_PATH], chInfo[_MAX_PATH];
wsprintf(chFilename, _T("%s"), szFilename);
wsprintf(chInfo, _T("Routine %s: PID %d(0x%X), TID %d(0x%X)\r\n"),
szRoutine, dwPID, dwPID, dwTID, dwTID);
HANDLE hFile = ::CreateFile(
chFilename, GENERIC_WRITE,
FILE_SHARE_READ, //not shared
NULL, // SD
OPEN_ALWAYS, // how to create
FILE_ATTRIBUTE_NORMAL, // file attributes
NULL // handle to template file
);
if(INVALID_HANDLE_VALUE == hFile)
{
::ReportErr(_T("Log File Open Failed"));
}
chASSERT(INVALID_HANDLE_VALUE != hFile);
LONG disp1, disp2;
disp1 = disp2 = 0;
SetFilePointer(hFile, disp1, &disp2, FILE_END);
int len = lstrlen(chInfo)*sizeof(TCHAR);
DWORD dwWritten;
BOOL bRet = ::WriteFile(hFile, // handle to file
chInfo, // data buffer
len, // number of bytes to write
&dwWritten,
NULL // offset
);
bRet;
chASSERT(dwWritten == (DWORD)len);
::CloseHandle(hFile);
cs.LeaveCriticalSection();
return TRUE;
}
//Thread Safe Version of WriteLineLog
BOOL WriteLineLogMT(LPCTSTR szFilename, LPCTSTR szMessage)
{
#ifndef _DEBUG
return TRUE;
#endif
static CZCriticalSection cs;
cs.EnterCriticalSection();
TCHAR chFilename[_MAX_PATH];
wsprintf(chFilename, _T("%s"), szFilename);
HANDLE hFile = ::CreateFile(
chFilename, GENERIC_WRITE,
FILE_SHARE_READ, //not shared
NULL, // SD
OPEN_ALWAYS, // how to create
FILE_ATTRIBUTE_NORMAL, // file attributes
NULL // handle to template file
);
if(INVALID_HANDLE_VALUE == hFile)
{
ReportErr(_T("Log File Open Failed"));
}
chASSERT(INVALID_HANDLE_VALUE != hFile);
LONG disp1, disp2;
disp1 = disp2 = 0;
SetFilePointer(hFile, disp1, &disp2, FILE_END);
TCHAR chLine[1024];
wsprintf(chLine, _T("%s\r\n"), szMessage);
//AfxMessageBox(szMessage);
int len = lstrlen(chLine)*sizeof(TCHAR);//lstrlen(szMessage) + 2;
DWORD dwWritten;
BOOL bRet = ::WriteFile(hFile, // handle to file
chLine, // data buffer
len, // number of bytes to write
&dwWritten,
NULL // offset
);
bRet;
chASSERT(dwWritten == (DWORD)len);
::CloseHandle(hFile);
cs.LeaveCriticalSection();
return TRUE;
}
BOOL WriteLineLog(LPCTSTR szFilename, LPCTSTR szMessage)
{
#ifndef _DEBUG
return TRUE;
#endif
TCHAR chFilename[_MAX_PATH];
wsprintf(chFilename, _T("%s"), szFilename);
HANDLE hFile = ::CreateFile(
chFilename, GENERIC_WRITE,
FILE_SHARE_READ, //not shared
NULL, // SD
OPEN_ALWAYS, // how to create
FILE_ATTRIBUTE_NORMAL, // file attributes
NULL // handle to template file
);
if(INVALID_HANDLE_VALUE == hFile)
{
::ReportErr(_T("Log File Open Failed"));
}
chASSERT(INVALID_HANDLE_VALUE != hFile);
LONG disp1, disp2;
disp1 = disp2 = 0;
SetFilePointer(hFile, disp1, &disp2, FILE_END);
TCHAR chLine[1024];
wsprintf(chLine, _T("%s\r\n"), szMessage);
//AfxMessageBox(szMessage);
int len = lstrlen(chLine)*sizeof(TCHAR);//lstrlen(szMessage) + 2;
DWORD dwWritten;
BOOL bRet = ::WriteFile(hFile, // handle to file
chLine, // data buffer
len, // number of bytes to write
&dwWritten,
NULL // offset
);
bRet;
chASSERT(dwWritten == (DWORD)len);
::CloseHandle(hFile);
return TRUE;
}
//SetCurrentPrivilege(NULL, L"SeDebugPrivilege", TRUE)
BOOL SetCurrentPrivilege(
LPWSTR TargetComputer, // target of privilege operation
LPCWSTR Privilege, // Privilege to enable/disable
BOOL bEnablePrivilege // to enable or disable privilege
)
{
HANDLE hToken;
TOKEN_PRIVILEGES tp;
LUID luid;
TOKEN_PRIVILEGES tpPrevious;
DWORD cbPrevious=sizeof(TOKEN_PRIVILEGES);
BOOL bSuccess=FALSE;
if(!LookupPrivilegeValueW(TargetComputer, Privilege, &luid))
return FALSE;
if(!OpenProcessToken(GetCurrentProcess(),
TOKEN_QUERY | TOKEN_ADJUST_PRIVILEGES,&hToken))
{
//::ReportErr(_T("OpenProcessToken"));
return FALSE;
}
// first pass. get current privilege setting
tp.PrivilegeCount = 1;
tp.Privileges[0].Luid = luid;
tp.Privileges[0].Attributes = 0;
AdjustTokenPrivileges(hToken, FALSE, &tp, sizeof(TOKEN_PRIVILEGES),
&tpPrevious, &cbPrevious);
if(GetLastError() == ERROR_SUCCESS) {
// second pass. set privilege based on previous setting
tpPrevious.PrivilegeCount = 1;
tpPrevious.Privileges[0].Luid = luid;
if(bEnablePrivilege) {
tpPrevious.Privileges[0].Attributes |=
(SE_PRIVILEGE_ENABLED);
}
else {
tpPrevious.Privileges[0].Attributes ^=
(SE_PRIVILEGE_ENABLED &
tpPrevious.Privileges[0].Attributes);
}
AdjustTokenPrivileges(hToken, FALSE, &tpPrevious,
cbPrevious, NULL, NULL);
if (GetLastError() == ERROR_SUCCESS) bSuccess=TRUE;
}
CloseHandle(hToken);
return bSuccess;
}
//SE_SHUTDOWN_NAME
void ShutDown()
{
SetCurrentPrivilege(NULL, L"SeShutdownPrivilege", TRUE);
ExitWindowsEx(EWX_REBOOT, 0);
}
void ReportWNetErr(DWORD dwErr, LPCTSTR str)
{
if(dwErr != ERROR_EXTENDED_ERROR)
{
LPVOID lpMsgBuf;
FormatMessage(
FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS,
NULL,
::GetLastError(),
MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), // Default language
(LPTSTR) &lpMsgBuf,
0,
NULL
);
::MessageBox( NULL, (LPCTSTR)lpMsgBuf,
str, MB_OK | MB_ICONINFORMATION );
// Free the buffer.
LocalFree( lpMsgBuf );
}
else
{
// The following code performs error-handling when the
// ERROR_EXTENDED_ERROR return value indicates that WNetGetLastError
// can retrieve additional information.
DWORD dwLastError;
TCHAR szDescription[256];
TCHAR szProvider[256];
TCHAR pszError[256];
DWORD dwResult = WNetGetLastError(
&dwLastError,
szDescription, // buffer for error description
sizeof(szDescription),
szProvider, // buffer for provider name
sizeof(szProvider)
);
if(dwResult != NO_ERROR) {
wsprintf(pszError,
TEXT("WNetGetLastError failed; error %ld"), dwResult);
} else {
szDescription[_tcsclen(szDescription)-2] = TEXT('\0'); //remove cr/nl characters
wsprintf(pszError,
TEXT("%s failed with code %ld (\"%s\")"),
szProvider, dwLastError, szDescription);
}
::MessageBox( NULL, (LPCTSTR)pszError,
str, MB_OK | MB_ICONINFORMATION );
}
}
void PopMsg(LPCTSTR pszFormat, ...)
{
va_list argList;
va_start(argList, pszFormat);
TCHAR sz[1024];
//#ifdef _UNICODE
// vswprintf(sz, pszFormat, argList);
//#else
// vsprintf(sz, pszFormat, argList);
//#endif
wvsprintf(sz, pszFormat, argList);
va_end(argList);
::MessageBox(NULL, sz, _T("Pop Msg"), MB_OK);
}
void ReportErr(LPCTSTR str)
{
LPVOID lpMsgBuf;
FormatMessage(
FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS,
NULL,
::GetLastError(),
MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), // Default language
(LPTSTR) &lpMsgBuf,
0,
NULL
);
::MessageBox( NULL, (LPCTSTR)lpMsgBuf,
str, MB_OK | MB_ICONINFORMATION );
// Free the buffer.
LocalFree( lpMsgBuf );
}
void ReportErrEx(LPCTSTR pszFormat, ...)
{
va_list argList;
va_start(argList, pszFormat);
TCHAR sz[1024];
wvsprintf(sz, pszFormat, argList);
va_end(argList);
LPVOID lpMsgBuf;
FormatMessage(
FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS,
NULL,
::GetLastError(),
MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), // Default language
(LPTSTR) &lpMsgBuf,
0,
NULL
);
::MessageBox( NULL, (LPCTSTR)lpMsgBuf,
sz, MB_OK | MB_ICONINFORMATION );
// Free the buffer.
LocalFree( lpMsgBuf );
}
LONG StringToHex(LPCTSTR strHex)
{
CString str = strHex;
if(str.Left(2).CompareNoCase(_T("0x")) == 0)
str = str.Right(str.GetLength() - 2);
str.MakeLower();
int nRet = 0;
int nExp = 1;
int len = str.GetLength();
for(int i = 1; i <= len; i++)
{
CString digital = str.Mid(len - i, 1);
int n;
TCHAR ch = digital.GetAt(0);
switch(ch)
{
case TCHAR('0'): n = 0; break;
case TCHAR('1'): n = 1; break;
case TCHAR('2'): n = 2; break;
case TCHAR('3'): n = 3; break;
case TCHAR('4'): n = 4; break;
case TCHAR('5'): n = 5; break;
case TCHAR('6'): n = 6; break;
case TCHAR('7'): n = 7; break;
case TCHAR('8'): n = 8; break;
case TCHAR('9'): n = 9; break;
case TCHAR('a'): n = 10; break;
case TCHAR('b'): n = 11; break;
case TCHAR('c'): n = 12; break;
case TCHAR('d'): n = 13; break;
case TCHAR('e'): n = 14; break;
case TCHAR('f'): n = 15; break;
}
nRet += n * nExp;
nExp *= 16;
}
return (LONG)nRet;
}
CString GetClipText()
{
#ifndef _UNICODE
HGLOBAL hGMem;
LPSTR pGMem;
CString str;
LPSTR pStr;
::OpenClipboard (AfxGetMainWnd()->GetSafeHwnd()) ;
hGMem = ::GetClipboardData (CF_TEXT);
if(hGMem == NULL) return _T("");
pGMem = (LPSTR)::GlobalLock (hGMem) ;
int len = ::strlen(pGMem);
pStr = str.GetBuffer(len);
::strncpy(pStr, (LPCTSTR)pGMem, len + 1);
str.ReleaseBuffer(len);
::GlobalUnlock (hGMem) ;
CloseClipboard();
return str;
#else
HGLOBAL hGMem;
LPSTR pGMem;
CString str;
::OpenClipboard (AfxGetMainWnd()->GetSafeHwnd()) ;
hGMem = ::GetClipboardData (CF_TEXT);
if(hGMem == NULL) return _T("");
pGMem = (LPSTR)::GlobalLock (hGMem) ;
int len = ::strlen(pGMem);
DWORD lenW;
LPWSTR pTemp = ::_A2W(pGMem, len, lenW);
if(lenW == 0)
{
//try _A2Wex
pTemp = ::_A2Wex(pGMem, len, lenW);
if(lenW == 0) return _T("");
else
{
::lstrcpy(str.GetBuffer(lenW), pTemp);
str.ReleaseBuffer(lenW);
::VirtualFree((LPVOID)pTemp, lenW*sizeof(WCHAR), MEM_RELEASE);
}
}
else
{
::lstrcpy(str.GetBuffer(lenW), pTemp);
str.ReleaseBuffer(lenW);
}
::GlobalUnlock (hGMem) ;
CloseClipboard();
return str;
#endif
}
void SetClipText(CString str)
{
#ifndef _UNICODE
HGLOBAL hGMem;
LPSTR pGMem;
LPSTR pStr;
::OpenClipboard (AfxGetMainWnd()->GetSafeHwnd()) ;
int len = str.GetLength();
hGMem = ::GlobalAlloc(GPTR, len + 1);
ASSERT(hGMem);
pGMem = (LPSTR)::GlobalLock (hGMem) ;
pStr = str.GetBuffer(len);
::strncpy(pGMem, pStr, len + 1);
str.ReleaseBuffer(len);
if(NULL == ::SetClipboardData(CF_TEXT, hGMem))
::ReportErr(_T("SetClipboardData"));
::GlobalUnlock (hGMem);
::CloseClipboard();
#else
HGLOBAL hGMem;
LPSTR pGMem;
::OpenClipboard (AfxGetMainWnd()->GetSafeHwnd()) ;
DWORD lenA;
LPSTR pTemp = ::_W2A((LPWSTR)(LPCWSTR)str, str.GetLength(), lenA);
if(lenA == 0)
{
//try _W2Aex
pTemp = ::_W2Aex((LPWSTR)(LPCWSTR)str, str.GetLength(), lenA);
if(lenA == 0) return;
else
{
hGMem = ::GlobalAlloc(GPTR, lenA+1);
ASSERT(hGMem);
pGMem = (LPSTR)::GlobalLock (hGMem) ;
::strncpy(pGMem, pTemp, lenA+1);
::VirtualFree((LPVOID)pTemp, lenA*sizeof(char), MEM_RELEASE);
}
}
else
{
hGMem = ::GlobalAlloc(GPTR, lenA+1);
ASSERT(hGMem);
pGMem = (LPSTR)::GlobalLock (hGMem) ;
::strncpy(pGMem, pTemp, lenA+1);
}
if(NULL == ::SetClipboardData(CF_TEXT, hGMem))
::ReportErr(_T("SetClipboardData"));
::GlobalUnlock (hGMem);
::CloseClipboard();
#endif
}
CString BrowsePath(CString strDescription, UINT uFlag)
{
CString strDir;
LPMALLOC lpmalloc;
LPITEMIDLIST lPIDL;
// Get the point of Shell IMalloc Interface
if (SUCCEEDED(::SHGetMalloc(&lpmalloc)))
{
// Get pointer to ID List
if (SUCCEEDED(::SHGetSpecialFolderLocation(NULL,
CSIDL_DESKTOP, &lPIDL)))
{
//Stuff BROWSEINFO
TCHAR buff[MAX_PATH];
BROWSEINFO binfo = {0};
binfo.hwndOwner = NULL; //m_hWnd;
binfo.lpszTitle = strDescription;
// CSIDL_DESKTOP'PIDL
binfo.pidlRoot = lPIDL;
// Buffer of Got Item
binfo.pszDisplayName = buff;
// File or Directory ?
binfo.ulFlags = uFlag; //BIF_BROWSEINCLUDEFILES;
// Browser Folder
LPITEMIDLIST pIDL = ::SHBrowseForFolder(&binfo);
if (!pIDL)
{
lpmalloc->Free(lPIDL);
lpmalloc->Release();
return _T("");
}
// Confirm PIDL and Item Name
CString pidlstr;
// Arrange String
//if you use the following sentence, add dis, then
//choose text & html type, ooooo$$$$$$$$$$$ funny!"""""
/*
::wsprintf((LPTSTR)((LPCTSTR)pidlstr),
"Following Items Selected\n\n"
"Item Name = �u%s�v\n"
"PIDL = %#x", buff, pIDL);
*/
//AfxMessageBox(pidlstr);
// Staff SHELLEXECUTEINFO
SHELLEXECUTEINFO sei = {0};
// Try To Get Path
TCHAR pathbuff[MAX_PATH];
if (::SHGetPathFromIDList(pIDL, pathbuff))
{
sei.lpFile = pathbuff;
}
else
{
// Use Mask
sei.fMask = SEE_MASK_IDLIST;
// CSIDL_HISTORY'PIDL
sei.lpIDList = pIDL;
}
strDir = pathbuff;
/*
//open the folder
sei.cbSize = sizeof(SHELLEXECUTEINFO);
sei.hwnd = m_hWnd;
sei.nShow = SW_SHOWNORMAL;
// Execute Shell
if (!::ShellExecuteEx(&sei) ||
(const int)sei.hInstApp <= 32)
{
AfxMessageBox("Fail");
lpmalloc->Free(pIDL);
lpmalloc->Free(lPIDL);
lpmalloc->Release();
return;
}
*/
lpmalloc->Free(pIDL);
lpmalloc->Free(lPIDL);
}
lpmalloc->Release();
}
return strDir;
}
CString BrowsePrinter(CString strDescription)
{
CString strDir;
LPMALLOC lpmalloc;
LPITEMIDLIST lPIDL;
// Get the point of Shell IMalloc Interface
if (SUCCEEDED(::SHGetMalloc(&lpmalloc)))
{
// Get pointer to ID List
if (SUCCEEDED(::SHGetSpecialFolderLocation(NULL,
CSIDL_DESKTOP, &lPIDL)))
{
//Stuff BROWSEINFO
TCHAR buff[MAX_PATH];
BROWSEINFO binfo = {0};
binfo.hwndOwner = NULL; //m_hWnd;
binfo.lpszTitle = strDescription;
// CSIDL_DESKTOP'PIDL
binfo.pidlRoot = lPIDL;
// Buffer of Got Item
binfo.pszDisplayName = buff;
// File or Directory ?
binfo.ulFlags = BIF_BROWSEFORPRINTER ;
// Browser Folder
LPITEMIDLIST pIDL = ::SHBrowseForFolder(&binfo);
if (!pIDL)
{
lpmalloc->Free(lPIDL);
lpmalloc->Release();
return _T("");
}
// Confirm PIDL and Item Name
CString pidlstr;
// Arrange String
//if you use the following sentence, add dis, then
//choose text & html type, ooooo$$$$$$$$$$$ funny!"""""
/*
::wsprintf((LPTSTR)((LPCTSTR)pidlstr),
"Following Items Selected\n\n"
"Item Name = �u%s�v\n"
"PIDL = %#x", buff, pIDL);
*/
//AfxMessageBox(pidlstr);
// Staff SHELLEXECUTEINFO
SHELLEXECUTEINFO sei = {0};
// Try To Get Path
TCHAR pathbuff[MAX_PATH];
if (::SHGetPathFromIDList(pIDL, pathbuff))
{
sei.lpFile = pathbuff;
}
else
{
// Use Mask
sei.fMask = SEE_MASK_IDLIST;
// CSIDL_HISTORY'PIDL
sei.lpIDList = pIDL;
}
strDir = pathbuff;
/*
//open the folder
sei.cbSize = sizeof(SHELLEXECUTEINFO);
sei.hwnd = m_hWnd;
sei.nShow = SW_SHOWNORMAL;
// Execute Shell
if (!::ShellExecuteEx(&sei) ||
(const int)sei.hInstApp <= 32)
{
AfxMessageBox("Fail");
lpmalloc->Free(pIDL);
lpmalloc->Free(lPIDL);
lpmalloc->Release();
return;
}
*/
lpmalloc->Free(pIDL);
lpmalloc->Free(lPIDL);
}
lpmalloc->Release();
}
return strDir;
}