private void FormMain_Load(object sender, EventArgs e) { // start the encryption thread pool to speed up the analyzer - this is also the first access to the native // "TrueCrypt.dll" and therefore an exception may occur when the library cannot be loaded try { TrueCrypt.EncryptionThreadPoolStart(Environment.ProcessorCount); } catch (DllNotFoundException) { MessageBox.Show(this, "Unable to load DLL \"TrueCrypt.dll\": This could be caused by a missing Microsoft Visual C++ 2010 Redistributable Package (x86).", Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Stop); silentExit = true; Close(); } // inform the user that some 64-bit operating systems are not supported due to driver signing string errMessage; SafeFileHandle hDriver = TrueCrypt.OpenDriver(out errMessage); if (null != errMessage) { errMessage += " Mounting a volume will not work."; if (Wow.Is64BitOperatingSystem && Wow.IsOSAtLeast(Wow.OSVersion.WIN_VISTA)) { errMessage += " A 64-bit operating system which requires signed drivers (Windows® Vista or newer) has been detected. Use the F8 boot option and select \"Disable Driver Signature Enforcement\" to temporarily allow the TestCrypt driver to be loaded."; } MessageBox.Show(this, errMessage, Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Warning); } }
/// <summary> /// Broadcasts a device change notification to inform the operating system about a device arrival/removal. /// </summary> /// <param name="message"></param> /// <param name="nDosDriveNo"></param> /// <param name="driveMap"></param> private static void BroadcastDeviceChange(uint message, int nDosDriveNo, uint driveMap) { uint eventId = 0; if (message == DBT_DEVICEARRIVAL) { eventId = SHCNE_DRIVEADD; } else if (message == DBT_DEVICEREMOVECOMPLETE) { eventId = SHCNE_DRIVEREMOVED; } else if (Wow.IsOSAtLeast(Wow.OSVersion.WIN_7) && message == DBT_DEVICEREMOVEPENDING) // Explorer on Windows 7 holds open handles of all drives when 'Computer' is expanded in navigation pane. SHCNE_DRIVEREMOVED must be used as DBT_DEVICEREMOVEPENDING is ignored. { eventId = SHCNE_DRIVEREMOVED; } if (driveMap == 0) { driveMap = (1U << nDosDriveNo); } if (eventId != 0) { for (int i = 0; i < 26; i++) { if (0 != (driveMap & (1U << i))) { IntPtr root = Marshal.StringToHGlobalAnsi(string.Format("{0}:\\", Char.ToString((char)('A' + i)))); SHChangeNotify(eventId, SHCNF_PATHA, root, IntPtr.Zero); Marshal.FreeHGlobal(root); } } } DEV_BROADCAST_VOLUME dbv = new DEV_BROADCAST_VOLUME(); dbv.dbcv_size = (uint)Marshal.SizeOf(typeof(DEV_BROADCAST_VOLUME)); dbv.dbcv_devicetype = DBT_DEVTYP_VOLUME; dbv.dbcv_reserved = 0; dbv.dbcv_unitmask = driveMap; dbv.dbcv_flags = 0; uint timeOut = 1000; // SHChangeNotify() works on Vista, so the Explorer does not require WM_DEVICECHANGE if (System.Environment.OSVersion.Version.Major >= 6) { timeOut = 100; } uint dwResult; IntPtr dbvPtr = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(DEV_BROADCAST_VOLUME))); Marshal.StructureToPtr(dbv, dbvPtr, true); SendMessageTimeout((IntPtr)HWND_BROADCAST, WM_DEVICECHANGE, message, dbvPtr, SMTO_ABORTIFHUNG, timeOut, out dwResult); // Explorer prior Vista sometimes fails to register a new drive if (System.Environment.OSVersion.Version.Major < 6 && message == DBT_DEVICEARRIVAL) { SendMessageTimeout((IntPtr)HWND_BROADCAST, WM_DEVICECHANGE, message, dbvPtr, SMTO_ABORTIFHUNG, 200, out dwResult); } Marshal.FreeHGlobal(dbvPtr); }