Example #1
0
    bool BackupTaskState(void) throw()
    {
        CPath path;
        bool bRet = false;

        if (GetIniFile(path))
        {
            CString temp;
            bRet = true;

            // get storage name
            if (GetConfigString(temp, path, _T("storage"), STORAGE_NAME))
            {
                path.RemoveFileSpec();
                path.Append(temp);

                if (path.FileExists())
                {
                    temp = (LPCTSTR)path; // store existing
                    path.RenameExtension(_T(".bak"));
                    bRet = (::MoveFileEx(temp, path, MOVEFILE_REPLACE_EXISTING) != 0);
                } 
            }
        }
        return bRet;
    }
Example #2
0
//設定から出力先フォルダを読み込む
//r_bUseForAll:今後も同じフォルダ設定を使うならtrue
HRESULT GetOutputDirPathFromConfig(OUTPUT_TO outputDirType,LPCTSTR lpszOrgFile,LPCTSTR lpszSpecific,CPath &r_pathOutputDir,bool &r_bUseForAll,CString &strErr)
{
	TCHAR szBuffer[_MAX_PATH+1];
	FILL_ZERO(szBuffer);

	switch(outputDirType){
	case OUTPUT_TO_SPECIFIC_DIR:	//Specific Directory
		//TRACE(_T("Specific Dir:%s\n"),Config.Common.Extract.OutputDir);
		r_pathOutputDir=lpszSpecific;
		if(_tcslen(r_pathOutputDir)>0){
			return S_OK;
		}else{
			//出力先がかかれていなければ、デスクトップに出力する
		}
		//FALLTHROUGH
	case OUTPUT_TO_DESKTOP:	//Desktop
		if(SHGetSpecialFolderPath(NULL,szBuffer,CSIDL_DESKTOPDIRECTORY,FALSE)){
			r_pathOutputDir=szBuffer;
		}else{	//デスクトップがない?
			strErr=CString(MAKEINTRESOURCE(IDS_ERROR_GET_DESKTOP));
			return E_FAIL;
		}
		return S_OK;
	case OUTPUT_TO_SAME_DIR:	//Same Directory
		_tcsncpy_s(szBuffer,lpszOrgFile,_MAX_PATH);
		PathRemoveFileSpec(szBuffer);
		r_pathOutputDir=szBuffer;
		return S_OK;
	case OUTPUT_TO_ALWAYS_ASK_WHERE:	//出力先を毎回聞く
		TRACE(_T("Always ask\n"));
		{
			//元のファイルと同じ場所にする;2回目以降は前回出力場所を使用する
			static CString s_strLastOutput;
			CPath pathTmp;
			if(s_strLastOutput.IsEmpty()){
				pathTmp=lpszOrgFile;
				pathTmp.RemoveFileSpec();
			}else{
				pathTmp=(LPCTSTR)s_strLastOutput;
			}

			CString title(MAKEINTRESOURCE(IDS_INPUT_TARGET_FOLDER_WITH_SHIFT));
			CLFFolderDialog dlg(NULL,title,BIF_RETURNONLYFSDIRS|BIF_NEWDIALOGSTYLE);
			dlg.SetInitialFolder(pathTmp);
			if(IDOK==dlg.DoModal()){
				r_bUseForAll=(GetKeyState(VK_SHIFT)<0);	//TODO
				r_pathOutputDir=dlg.GetFolderPath();
				s_strLastOutput=(LPCTSTR)r_pathOutputDir;
				return S_OK;
			}else{
				return E_ABORT;	//キャンセルされた
			}
		}
		break;
	default:
		ASSERT(!"This code cannot be run");
		return E_NOTIMPL;
	}
}
Example #3
0
    int ReadConfig(void) throw()
    {
        CPath path;

        if (GetIniFile(path))
        {
            int f = ::GetPrivateProfileInt(_T("server"), _T("family"), 0, path);
            m_family = (f == 4)? AF_INET : (f == 6)? AF_INET6 : DEFAULT_FAMILY;

            m_bCircular  = !!::GetPrivateProfileInt(_T("server"), _T("circular"), 0, path);
            m_MaxConnect = ::GetPrivateProfileInt(_T("server"), _T("maxconnect"), m_MaxConnect, path);

            CString buf;

            if (GetConfigString(buf, path, _T("ipaddress"))) { m_addr = buf; }

            if (GetConfigString(buf, path, _T("port"))) { m_port = buf; }

            if (GetConfigString(buf, path, _T("protocol")))
            {
                if (buf.CompareNoCase(_T("TCP")) == 0)
                {
                    m_socktype = SOCK_STREAM;
                }
                else if (buf.CompareNoCase(_T("UDP")) == 0)
                {
                    m_socktype = SOCK_DGRAM;
                }
            }

            // get storage name and interval
            CTask& task = CFactorySingleton<CTask>::Instance();

            UINT interval = ::GetPrivateProfileInt(_T("server"), _T("interval"), 0, path);

            if (interval > 0) { task.SetInterval(interval); }

            if (GetConfigString(buf, path, _T("storage"), STORAGE_NAME))
            {
                path.RemoveFileSpec();
                path.Append(buf);

                task.LoadState(path);
            }
        }

        return ERROR_SUCCESS;
    }
Example #4
0
BOOL CUnique::IsFilterFile( const CString& FilePath )
{
    if ( FALSE == WinMod::CWinPathApi::IsFileExisting(FilePath) )
    {
        //文件存在。但判断不出。如pagefile.sys
        return TRUE;
    }
    BOOL bFilter = FALSE;
    CPath DirPath = FilePath;
    DirPath.RemoveFileSpec();
    BOOL bTemp = FALSE;
    if ( _IsFindFile(FilePath) || _IsFindDir(DirPath.m_strPath, bTemp) )
    {
        //是提交过的文件,或文件所在目录为,扫描过的目录。
        bFilter = TRUE;
    }
    return bFilter;
}
Example #5
0
void Config::Save()
{
	CXmlWriter XmlWriter;
	XmlWriter.Open("root");

	XmlWriter.AddNewElement("SizeMode");
	XmlWriter.Write("value", Config::SizeMode);

	XmlWriter.AddNewElement("SkinTheme");
	XmlWriter.Write("value", Config::SkinTheme);

	XmlWriter.AddNewElement("ShowFloatBar");
	XmlWriter.Write("value", Config::ShowFloatBar ? 1 : 0);

	XmlWriter.AddNewElement("wVirtualKeyCode");
	XmlWriter.Write("value", Config::wVirtualKeyCode);

	XmlWriter.AddNewElement("wModifiers");
	XmlWriter.Write("value", Config::wModifiers);

	XmlWriter.AddNewElement("CloseMode");
	XmlWriter.Write("value", Config::CloseMode);

	XmlWriter.AddNewElement("StartupMode");
	XmlWriter.Write("value", Config::StartupMode);

	XmlWriter.AddNewElement("Transparent");
	XmlWriter.Write("value", Config::Transparent ? 1 : 0);

	XmlWriter.AddNewElement("TransparentPercent");
	XmlWriter.Write("value", Config::TransparentPercent);


	TCHAR szPath[MAX_PATH + 1] = _T(""); 
	::GetModuleFileName(NULL, szPath, MAX_PATH);
	CPath SaveFile;
	SaveFile = szPath;

	SaveFile.RemoveFileSpec();
	SaveFile.Append(L"config.dat");

	XmlWriter.WriteFile(CStringA(SaveFile));
}
Example #6
0
HRESULT CHdmvClipInfo::ReadChapters(CString strPlaylistFile, CAtlList<CHdmvClipInfo::PlaylistItem>& PlaylistItems, CAtlList<PlaylistChapter>& Chapters)
{
	BYTE				Buff[100];
	CPath				Path (strPlaylistFile);
	bool				bDuplicate = false;

	// Get BDMV folder
	Path.RemoveFileSpec();
	Path.RemoveFileSpec();

	m_hFile   = CreateFile(strPlaylistFile, GENERIC_READ, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL,
						   OPEN_EXISTING, FILE_ATTRIBUTE_READONLY|FILE_FLAG_SEQUENTIAL_SCAN, NULL);

	if(m_hFile != INVALID_HANDLE_VALUE)
	{
		REFERENCE_TIME*		rtOffset = new REFERENCE_TIME[PlaylistItems.GetCount()];
		REFERENCE_TIME		rtSum	 = 0;
		int					nIndex   = 0;

		POSITION		pos = PlaylistItems.GetHeadPosition();
		while(pos)
		{
			CHdmvClipInfo::PlaylistItem& PI = PlaylistItems.GetNext(pos);

			rtOffset[nIndex] = rtSum - PI.m_rtIn;
			rtSum			 = rtSum + PI.Duration();
			nIndex++;
		}

		ReadBuffer(Buff, 4);
		if (memcmp (Buff, "MPLS", 4)) {
			SAFE_DELETE_ARRAY(rtOffset);
			return CloseFile(VFW_E_INVALID_FILE_FORMAT);
		}

		ReadBuffer(Buff, 4);
		if ((memcmp (Buff, "0200", 4)!=0) && (memcmp (Buff, "0100", 4)!=0)) {
			SAFE_DELETE_ARRAY(rtOffset);
			return CloseFile(VFW_E_INVALID_FILE_FORMAT);
		}

		DWORD				dwPos;
		DWORD				dwTemp;
		SHORT				nMarkCount;

		ReadDword();			// PlayList_start_address
		dwPos	= ReadDword();	// PlayListMark_start_address

		// PlayListMark()
		SetFilePointer(m_hFile, dwPos, NULL, FILE_BEGIN);
		ReadDword();				// length
		nMarkCount = ReadShort();	// number_of_PlayList_marks
		for (size_t i=0; i<nMarkCount; i++)
		{
			PlaylistChapter	Chapter;

			ReadByte();												// reserved_for_future_use
			Chapter.m_nMarkType		= (PlaylistMarkType)ReadByte();	// mark_type 
			Chapter.m_nPlayItemId	= ReadShort();					// ref_to_PlayItem_id
			Chapter.m_rtTimestamp	= 20000i64*ReadDword()/90 + rtOffset[Chapter.m_nPlayItemId];		// mark_time_stamp
			Chapter.m_nEntryPID		= ReadShort();					// entry_ES_PID
			Chapter.m_rtDuration	= 20000i64*ReadDword()/90;		// duration

			Chapters.AddTail (Chapter);

			// TRACE ("Chapter %d : %S\n", i, ReftimeToString (Chapter.m_rtTimestamp));
		}

		CloseFile (S_OK);
		SAFE_DELETE_ARRAY(rtOffset);
		return bDuplicate ? S_FALSE : S_OK;
	}

	return AmHresultFromWin32(GetLastError());
}
Example #7
0
HRESULT CHdmvClipInfo::ReadPlaylist(CString strPlaylistFile, REFERENCE_TIME& rtDuration, CAtlList<PlaylistItem>& Playlist)
{

	BYTE				Buff[100];
	CPath				Path (strPlaylistFile);
	bool				bDuplicate = false;
	rtDuration  = 0;

	// Get BDMV folder
	Path.RemoveFileSpec();
	Path.RemoveFileSpec();

	m_hFile   = CreateFile(strPlaylistFile, GENERIC_READ, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL,
						   OPEN_EXISTING, FILE_ATTRIBUTE_READONLY|FILE_FLAG_SEQUENTIAL_SCAN, NULL);

	if(m_hFile != INVALID_HANDLE_VALUE) {
		ReadBuffer(Buff, 4);
		if (memcmp (Buff, "MPLS", 4)) {
			return CloseFile(VFW_E_INVALID_FILE_FORMAT);
		}

		ReadBuffer(Buff, 4);
		if ((memcmp (Buff, "0200", 4)!=0) && (memcmp (Buff, "0100", 4)!=0)) {
			return CloseFile(VFW_E_INVALID_FILE_FORMAT);
		}

		DWORD				dwPos;
		DWORD				dwTemp;
		SHORT				nPlaylistItems;

		dwPos	= ReadDword();		// PlayList_start_address
		ReadDword();				// PlayListMark_start_address

		// PlayList()
		SetFilePointer(m_hFile, dwPos, NULL, FILE_BEGIN);
		ReadDword();						// length 
		ReadShort();						// reserved_for_future_use
		nPlaylistItems = ReadShort();		// number_of_PlayItems
		ReadShort();						// number_of_SubPaths

		dwPos	  += 10;
		for (size_t i=0; i<nPlaylistItems; i++) {
			PlaylistItem	Item;
			SetFilePointer(m_hFile, dwPos, NULL, FILE_BEGIN);
			dwPos = dwPos + ReadShort() + 2;
			ReadBuffer(Buff, 5);
			Item.m_strFileName.Format(_T("%s\\STREAM\\%c%c%c%c%c.M2TS"), Path, Buff[0], Buff[1], Buff[2], Buff[3], Buff[4]);

			ReadBuffer(Buff, 4);
			if (memcmp (Buff, "M2TS", 4)) {
				return CloseFile(VFW_E_INVALID_FILE_FORMAT);
			}
			ReadBuffer(Buff, 3);

			dwTemp	= ReadDword();
			Item.m_rtIn = 20000i64*dwTemp/90;	// Carefull : 32->33 bits!

			dwTemp	= ReadDword();
			Item.m_rtOut = 20000i64*dwTemp/90;	// Carefull : 32->33 bits!

			rtDuration += (Item.m_rtOut - Item.m_rtIn);

			if (Playlist.Find(Item) != NULL) {
				bDuplicate = true;
			}
			Playlist.AddTail (Item);

			//TRACE ("File : %S, Duration : %S, Total duration  : %S\n", strTemp, ReftimeToString (rtOut - rtIn), ReftimeToString (rtDuration));
		}

		CloseFile (S_OK);
		return bDuplicate ? S_FALSE : S_OK;
	}

	return AmHresultFromWin32(GetLastError());
}
Example #8
0
HRESULT CHdmvClipInfo::ReadPlaylist(CString strPlaylistFile, REFERENCE_TIME& rtDuration, CPlaylist& Playlist, BOOL bFullInfoRead)
{

	BYTE	Buff[5];
	CPath	Path (strPlaylistFile);
	bool	bDuplicate = false;
	rtDuration  = 0;

	// Get BDMV folder
	Path.RemoveFileSpec();
	Path.RemoveFileSpec();

	m_hFile = CreateFile(strPlaylistFile, GENERIC_READ, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL,
							OPEN_EXISTING, FILE_ATTRIBUTE_READONLY|FILE_FLAG_SEQUENTIAL_SCAN, NULL);

	if (m_hFile != INVALID_HANDLE_VALUE) {
		DbgLog((LOG_TRACE, 3, _T("CHdmvClipInfo::ReadPlaylist() : %s"), strPlaylistFile));

		ReadBuffer(Buff, 4);
		if (memcmp(Buff, "MPLS", 4)) {
			return CloseFile(VFW_E_INVALID_FILE_FORMAT);
		}

		ReadBuffer(Buff, 4);
		if ((memcmp(Buff, "0200", 4)) && (memcmp(Buff, "0100", 4))) {
			return CloseFile(VFW_E_INVALID_FILE_FORMAT);
		}

		LARGE_INTEGER	Pos = {0, 0};
		DWORD			dwTemp;
		USHORT			nPlaylistItems;

		Pos.QuadPart = ReadDword();	// PlayList_start_address
		ReadDword();				// PlayListMark_start_address

		// PlayList()
		SetFilePointerEx(m_hFile, Pos, NULL, FILE_BEGIN);
		ReadDword();						// length
		ReadShort();						// reserved_for_future_use
		nPlaylistItems = ReadShort();		// number_of_PlayItems
		ReadShort();						// number_of_SubPaths

		Pos.QuadPart += 10;
		__int64 TotalSize = 0;
		for (size_t i = 0; i < nPlaylistItems; i++) {
			CAutoPtr<PlaylistItem> Item(DNew PlaylistItem);
			SetFilePointerEx(m_hFile, Pos, NULL, FILE_BEGIN);
			Pos.QuadPart += ReadShort() + 2;
			ReadBuffer(Buff, 5);
			Item->m_strFileName.Format(_T("%s\\STREAM\\%c%c%c%c%c.M2TS"), CString(Path), Buff[0], Buff[1], Buff[2], Buff[3], Buff[4]);

			ReadBuffer(Buff, 4);
			if (memcmp(Buff, "M2TS", 4)) {
				return CloseFile(VFW_E_INVALID_FILE_FORMAT);
			}

			if (!::PathFileExists(Item->m_strFileName)) {
				DbgLog((LOG_TRACE, 3, _T("		==> %s is missing, skip it"), Item->m_strFileName));
				continue;
			}
			ReadBuffer(Buff, 3);

			dwTemp				= ReadDword();
			Item->m_rtIn		= REFERENCE_TIME(20000.0f*dwTemp/90);

			dwTemp				= ReadDword();
			Item->m_rtOut		= REFERENCE_TIME(20000.0f*dwTemp/90);

			Item->m_rtStartTime	= rtDuration;

			rtDuration += (Item->m_rtOut - Item->m_rtIn);

			if (bFullInfoRead) {
				LARGE_INTEGER size = {0, 0};
				HANDLE hFile = CreateFile(Item->m_strFileName, GENERIC_READ, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL,
											OPEN_EXISTING, FILE_ATTRIBUTE_READONLY|FILE_FLAG_SEQUENTIAL_SCAN, NULL);
				if (hFile != INVALID_HANDLE_VALUE) {
					GetFileSizeEx(hFile, &size);
					CloseHandle(hFile);
				}

				Item->m_SizeIn	= TotalSize;
				TotalSize		+= size.QuadPart;
				Item->m_SizeOut	= TotalSize;
			}

			POSITION pos = Playlist.GetHeadPosition();
			while (pos) {
				PlaylistItem* pItem = Playlist.GetNext(pos);
				if (*pItem == *Item) {
					bDuplicate = true;
					break;
				}

			}

			DbgLog((LOG_TRACE, 3, _T("	==> %s, Duration : %s [%15I64d], Total duration : %s, Size : %I64d"), Item->m_strFileName, ReftimeToString(Item->Duration()), Item->Duration(), ReftimeToString(rtDuration), Item->Size()));

			Playlist.AddTail(Item);
		}

		CloseFile(S_OK);

		if (bFullInfoRead) {
			POSITION pos = Playlist.GetHeadPosition();
			while (pos) {
				PlaylistItem* pItem = Playlist.GetNext(pos);
				CString fname = pItem->m_strFileName;
				fname.Replace(L"\\STREAM\\", L"\\CLIPINF\\");
				fname.Replace(L".M2TS", L".CLPI");

				ReadInfo(fname, &pItem->m_sps);
			}
		}

		return Playlist.IsEmpty() ? E_FAIL : bDuplicate ? S_FALSE : S_OK;
	}

	return AmHresultFromWin32(GetLastError());
}
Example #9
0
UINT_PTR CNavDesktopModule::Main()
{
	if (!CheckInstance())
	{
		return 0;
	}

	if (_InitDownInterface())
	{
		_UpdateSelf();//程序升级
		_UpdateXmlConfig();//更新界面布局xml文件 
	}

	CMessageLoop theLoop;
	_Module.AddMessageLoop(&theLoop);

	{
		TCHAR szPath[MAX_PATH + 1] = _T(""); 
		::GetModuleFileName(NULL, szPath, MAX_PATH);
		CPath ConfigFile;
		ConfigFile = szPath;

		ConfigFile.RemoveFileSpec();
		ConfigFile.Append(L"config.dat");

		CXmlReader XmlReader;
		if (XmlReader.LoadFile(CStringA(ConfigFile)))
		{
			if (XmlReader.Open("root\\SizeMode"))
				XmlReader.Read("value", Config::SizeMode);

			if (XmlReader.Open("root\\SkinTheme"))
				XmlReader.Read("value", Config::SkinTheme);

			if (XmlReader.Open("root\\ShowFloatBar"))
				XmlReader.Read("value", Config::ShowFloatBar);

			if (XmlReader.Open("root\\wVirtualKeyCode"))
				XmlReader.Read("value", (int&)Config::wVirtualKeyCode);

			if (XmlReader.Open("root\\wModifiers"))
				XmlReader.Read("value", (int&)Config::wModifiers);

			if (XmlReader.Open("root\\CloseMode"))
				XmlReader.Read("value", Config::CloseMode);

			if (XmlReader.Open("root\\StartupMode"))
				XmlReader.Read("value", Config::StartupMode);

			if (XmlReader.Open("root\\Transparent"))
				XmlReader.Read("value", Config::Transparent);

			if (XmlReader.Open("root\\TransparentPercent"))
				XmlReader.Read("value", Config::TransparentPercent);
		}
	}

	CMainWnd MainWnd;
	if (MainWnd.Create(NULL) == NULL)
	{
		ATLTRACE(_T("Main dialog creation failed!\n"));
		return 0;
	}

	int nRet = theLoop.Run();
	_Module.RemoveMessageLoop();

	return nRet;
}
DWORD WINAPI DlgThread(LPVOID lpParameter)
{
	UINT i;
    int ret = 0;
	CPhotoResizeDlg waitDlg;
	CThreadInfo * threadInfo = (CThreadInfo *)lpParameter;
	CAtlArray<ResizeThread *> taskArray;

	::CoInitialize(NULL);

    if(IDOK == waitDlg.DoModal(threadInfo->m_hwnd))
	{
		CPath pathSource;
		CPath pathDirectory;
		CString strTitle, strCancel;
		size_t numFiles = threadInfo->m_aFiles.GetCount();
		CThreadPool<CWorker> m_threadPool;
		LONG interlockedCounter = 0;
		LONG interlockedShutdown = 0;
		ResizeThread *resizeThread;
		ImageHelperParam * pImageHelperParam;
		SYSTEM_INFO sysinfo;


		// create the progress dialog
		CComPtr<IProgressDialog> pProgressDialog;		
		pProgressDialog.CoCreateInstance(CLSID_ProgressDialog);			

		if (pProgressDialog != NULL)
		{
			strTitle.LoadString(IDS_RESIZING);
			strCancel.LoadString(IDS_CANCELING);

			pProgressDialog->SetTitle(strTitle.GetBuffer());
			// 0x020 is PROGDLG_MARQUEEPROGRESS, vc2008 couldn't find the definition
			// prog dlg doesn't list file names anymore since work is overlapped.
			pProgressDialog->StartProgressDialog(threadInfo->m_hwnd, NULL, 0x00000020, NULL);
			
			pProgressDialog->SetCancelMsg(strCancel.GetBuffer(), NULL);			
			pProgressDialog->SetLine(1, strTitle.GetBuffer(), FALSE, NULL);						
		}

		pImageHelperParam = new ImageHelperParam();
		pImageHelperParam->m_size = waitDlg.GetSize();
		pImageHelperParam->m_width = waitDlg.GetWidth();
		pImageHelperParam->m_height = waitDlg.GetHeight();
		pImageHelperParam->m_smallerOnly = waitDlg.IsSmallerOnly();
		pImageHelperParam->m_overwriteOriginal = waitDlg.IsOverwriteOriginal();
	
		// get number of cores/cpus on system. 
		// max number of threads is either number of cores or number of files
		GetSystemInfo(&sysinfo);		
		if(numFiles > sysinfo.dwNumberOfProcessors)
		{
			m_threadPool.Initialize((void *)pImageHelperParam, sysinfo.dwNumberOfProcessors);			
		}
		else
		{
			m_threadPool.Initialize((void *)pImageHelperParam, numFiles);
		}	

		// queue tasks to thread pool
		for (i = 0; i < numFiles; i++)
		{		
			pathSource = threadInfo->m_aFiles[i];

			if (CString(threadInfo->m_pathFolder).IsEmpty())
			{
				pathDirectory = pathSource;
				pathDirectory.RemoveFileSpec();
			}	
													
			resizeThread = new ResizeThread(pathSource, pathDirectory, &interlockedCounter, &interlockedShutdown);
			taskArray.Add(resizeThread);
			
			m_threadPool.QueueRequest((CWorker::RequestType)resizeThread);
			
			// increment counter for each task
			InterlockedIncrement(&interlockedCounter);
		}

		// worker threads decrement counter for each task they complete,
		// when the counter reaches zero, we're done.
		while(interlockedCounter > 0)
		{
			if(pProgressDialog != NULL && pProgressDialog->HasUserCancelled())
			{	
				// will cause worker thread to skip the actual resize tasks and just
				// mark themselves as completed.
				InterlockedExchange(&interlockedShutdown, 1);
				// wait for task count to go to zero
				while(interlockedCounter > 0)
				{
					Sleep(50);
				}
				m_threadPool.Shutdown(5 * 1000); // give it 5 seconds to shutdown, but all tasks should be done by now		
				// bug in cthreadpool, will throw an assertion in debug mode if tasks still exist after the timeout
				// http://groups.google.com/group/microsoft.public.vc.atl/browse_thread/thread/c3d77f272fde2816/93b94461766ded0f?lnk=st&amp;q=CThreadPool&amp;rnum=1#93b94461766ded0f
				// so, we don't want any current tasks when the shutdown times out
				// otherwise we could have resource/handle leaks
				// really should implement a thread pool that shuts down properly
				break;
			}
			Sleep(100); // wait a bit
		}				
		
		if (pProgressDialog != NULL)
		{
			pProgressDialog->StopProgressDialog();
			pProgressDialog.Release();
		}

		if(NULL != pImageHelperParam)
		{
			delete pImageHelperParam;
		}

		// delete tasks
		for(i = 0; i < taskArray.GetCount(); i++)
		{
			resizeThread = taskArray[i];
			if(NULL != resizeThread)
			{
				delete resizeThread;
			}
		}
		taskArray.RemoveAll();

		m_threadPool.Release();
	}

	if(NULL != threadInfo)
	{
		delete threadInfo;
		threadInfo = NULL;
	}

	::CoUninitialize();

    return ret;
}