Click here to Skip to main content
15,895,746 members
Articles / Programming Languages / C++

GUI-Based RunAsEx

Rate me:
Please Sign up or sign in to vote.
4.97/5 (61 votes)
24 Oct 2006CPOL42 min read 401.3K   10.8K   200  
An ultimate tool that lets you RunAs... (With support for non-Pwd, WTS, fake privilege, fake user groups, etc...)
/************************************
  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;
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Other
United States United States
fdefewtr534554yutki8op09;[pio';l.n,kbnmcvbxcvzxaqW876876UIYIUJUGHJGFHYFGHRDTR4564QWEDASASFDXCBVCBNGHNMJHMJN,NJKL;O[P-0=-]'[P';L/L,M.NM,BNMCGNGFXDGDFGTYU76TRYW34TR5AWERFASDVGfdsxbvfbvnvnm,jkl.k

Comments and Discussions