Win32 API功能封装
+ -

Windows下隐藏盘符

2021-08-30 114 0

在windows下,有时我们需要隐藏某个分区
当有隐藏磁盘分区的需求时可以通过修改注册表来实现在不删除盘符的情况下使分区不在资源管理器中显示,但不会修改盘符以及影响分区中的数据,仅仅只是在资源管理器中不再显示,可以理解为视觉上的隐藏
适合在保证磁盘分区能正常使用的情况下让电脑使用者看不见某一些分区

win+r运行regedit打开注册表管理器
找到:计算机

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Explorer

选中Explorer右键选新建选DWORD(32),新建一个注册表NoDrives,当然如果你分区超过32个的话,选64位(其实我还在想盘符A~Z可分配,超过这个数了咋整)

当然我们也可以通过代码来实现:
假如我们要隐藏A盘


#include "stdafx.h"
#include <windows.h>
#include <IPHlpApi.h>
#pragma comment(lib,"IPHlpApi.lib")
#include <WinNetWk.h>

#include <Shlobj.h>
#include <dbt.h>
#pragma comment(lib,"Mpr.lib")
#pragma comment(lib, "shlwapi.lib")


BOOL ReadRegistryDword(LPCTSTR lpSubKey, LPCTSTR lpName, DWORD *dwValue)
{
    HKEY hKey = 0;
    DWORD dwSize = sizeof(*dwValue);
    DWORD dwType;
    LONG lStatus;
    SECURITY_ATTRIBUTES sa;
    sa.nLength = sizeof(SECURITY_ATTRIBUTES);
    sa.bInheritHandle = TRUE;
    sa.lpSecurityDescriptor = NULL;

    lStatus = RegOpenKeyEx(HKEY_CURRENT_USER, lpSubKey, 0, KEY_READ, &hKey);
    if (lStatus != ERROR_SUCCESS)
    {
        SetLastError(lStatus);
        return FALSE;
    }

    lStatus = RegQueryValueEx(hKey, lpName, NULL, &dwType, (BYTE *)dwValue, &dwSize);
    if (lStatus != ERROR_SUCCESS)
    {
        RegCloseKey(hKey);
        SetLastError(lStatus);
        return FALSE;
    }

    RegCloseKey(hKey);
    return dwType == REG_DWORD;
}

BOOL WriteRegistryDword(LPCTSTR lpSubKey, LPCTSTR lpName, DWORD dwValue)
{
    HKEY hKey = 0;
    DWORD dwDisp;
    LONG lStatus;
    SECURITY_ATTRIBUTES sa;
    sa.nLength = sizeof(SECURITY_ATTRIBUTES);
    sa.bInheritHandle = TRUE;
    sa.lpSecurityDescriptor = NULL;

    lStatus = RegCreateKeyEx(HKEY_CURRENT_USER, lpSubKey, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_WRITE, &sa, &hKey, &dwDisp);
    if (lStatus != ERROR_SUCCESS)
    {
        SetLastError(lStatus);
        return FALSE;
    }

    lStatus = RegSetValueEx(hKey, lpName, 0, REG_DWORD, (BYTE *)&dwValue, sizeof dwValue);
    if (lStatus != ERROR_SUCCESS)
    {
        RegCloseKey(hKey);
        SetLastError(lStatus);
        return FALSE;
    }

    RegCloseKey(hKey);
    return TRUE;
}


void HideVolume(int nDriveNo)
{
    DWORD dwResult;
    DEV_BROADCAST_VOLUME* p01 = new DEV_BROADCAST_VOLUME;
    p01->dbcv_devicetype = 2;
    p01->dbcv_flags = 0;
    p01->dbcv_size = 20;
    p01->dbcv_unitmask = (1 << nDriveNo);
    char szRoot[] = { (char)(nDriveNo + 'A'), ':', '', 0 };
    SHChangeNotify(SHCNE_DRIVEREMOVED, SHCNF_PATH, szRoot, NULL);
    DWORD dwRecipients = BSM_APPLICATIONS;
    BroadcastSystemMessage(BSF_IGNORECURRENTTASK | BSF_POSTMESSAGE | BSF_FORCEIFHUNG, &dwRecipients,
        WM_DEVICECHANGE, DBT_DEVNODES_CHANGED, NULL);
    dwRecipients = BSM_APPLICATIONS;
    BroadcastSystemMessage(BSF_IGNORECURRENTTASK | BSF_POSTMESSAGE | BSF_FORCEIFHUNG, &dwRecipients,
        WM_DEVICECHANGE, DBT_DEVICEREMOVECOMPLETE, (LPARAM)p01);
    DWORD value = 0;
    LPCTSTR skey = _T("SoftwareMicrosoftWindowsCurrentVersionPoliciesExplorer");
    if (!ReadRegistryDword(skey, _T("NoDrives"), &value))
    {
        value = 0;
    }
    value |= (1 << nDriveNo);
    WriteRegistryDword(skey, _T("NoDrives"), value);
    SHChangeNotify(SHCNE_DRIVEREMOVED, SHCNF_PATH, szRoot, NULL);
    //DWORD dwRecipients = BSM_APPLICATIONS;
    BroadcastSystemMessage(BSF_IGNORECURRENTTASK | BSF_POSTMESSAGE | BSF_FORCEIFHUNG, &dwRecipients,WM_DEVICECHANGE, DBT_DEVNODES_CHANGED, NULL);
    dwRecipients = BSM_APPLICATIONS;
    BroadcastSystemMessage(BSF_IGNORECURRENTTASK | BSF_POSTMESSAGE | BSF_FORCEIFHUNG, &dwRecipients,WM_DEVICECHANGE, DBT_DEVICEREMOVECOMPLETE, (LPARAM)p01);
    delete[] p01;

    SendMessageTimeout(HWND_BROADCAST, WM_SETTINGCHANGE, 0, LPARAM("Policy"), SMTO_ABORTIFHUNG, 500, &dwResult);
}
void ShowVolume(int nDriveNo)
{
    DWORD dwResult;
    DEV_BROADCAST_VOLUME* p01 = new DEV_BROADCAST_VOLUME;
    p01->dbcv_devicetype = 2;
    p01->dbcv_flags = 0;
    p01->dbcv_size = 20;
    p01->dbcv_unitmask = (1 << nDriveNo);//H
    char szRoot[] = { (char)(nDriveNo + 'A'), ':', '', 0 };
    SHChangeNotify(SHCNE_DRIVEADD, SHCNF_PATH, szRoot, NULL);
    SHChangeNotify(SHCNE_UPDATEDIR, SHCNF_PATH, szRoot, NULL);
    DWORD dwRecipients = BSM_APPLICATIONS;
    BroadcastSystemMessage(BSF_IGNORECURRENTTASK | BSF_POSTMESSAGE | BSF_FORCEIFHUNG, &dwRecipients,WM_DEVICECHANGE, DBT_DEVNODES_CHANGED, NULL);
    dwRecipients = BSM_APPLICATIONS;
    BroadcastSystemMessage(BSF_IGNORECURRENTTASK | BSF_POSTMESSAGE | BSF_FORCEIFHUNG, &dwRecipients,WM_DEVICECHANGE, DBT_DEVICEARRIVAL, (LPARAM)p01);
    dwRecipients = BSM_APPLICATIONS;
    BroadcastSystemMessage(BSF_IGNORECURRENTTASK | BSF_POSTMESSAGE | BSF_FORCEIFHUNG, &dwRecipients,WM_DEVICECHANGE, DBT_DEVNODES_CHANGED, NULL);

    DWORD value = 0;
    LPCTSTR skey = _T("SoftwareMicrosoftWindowsCurrentVersionPoliciesExplorer");
    if (!ReadRegistryDword(skey, _T("NoDrives"), &value))
    {
        value = 0;
    }
    value &= ~(1 << nDriveNo);
    WriteRegistryDword(skey, _T("NoDrives"), value);
    SHChangeNotify(SHCNE_DRIVEADD, SHCNF_PATH, szRoot, NULL);
    SHChangeNotify(SHCNE_UPDATEDIR, SHCNF_PATH, szRoot, NULL);
    // DWORD dwRecipients = BSM_APPLICATIONS;
    BroadcastSystemMessage(BSF_IGNORECURRENTTASK | BSF_POSTMESSAGE | BSF_FORCEIFHUNG, &dwRecipients,WM_DEVICECHANGE, DBT_DEVNODES_CHANGED, NULL);
    dwRecipients = BSM_APPLICATIONS;
    BroadcastSystemMessage(BSF_IGNORECURRENTTASK | BSF_POSTMESSAGE | BSF_FORCEIFHUNG, &dwRecipients,WM_DEVICECHANGE, DBT_DEVICEARRIVAL, (LPARAM)p01);
    dwRecipients = BSM_APPLICATIONS;
    BroadcastSystemMessage(BSF_IGNORECURRENTTASK | BSF_POSTMESSAGE | BSF_FORCEIFHUNG, &dwRecipients,WM_DEVICECHANGE, DBT_DEVNODES_CHANGED, NULL);
    delete[] p01;
    SendMessageTimeout(HWND_BROADCAST, WM_SETTINGCHANGE, 0, LPARAM("Policy"), SMTO_ABORTIFHUNG, 500, &dwResult);
}


int _tmain(int argc, _TCHAR* argv[])
{
        HideVolume(0);
        return 0;
}

完成以上操作后,需要重启explorer.exe进程或者重启电脑。

0 篇笔记 写笔记

Windows下获取盘符信息
在Windows 下,各盘符其实是系统中一个文件,我们了可以通过CreateFile来打开,然后再通过DeviceIoControl函数发送不同的控制码获取相关的信息。这里的信息包括盘符大小,StartingOffset,DiskNumber,ExtentLength等。#include<......
Windows下隐藏盘符
在windows下,有时我们需要隐藏某个分区当有隐藏磁盘分区的需求时可以通过修改注册表来实现在不删除盘符的情况下使分区不在资源管理器中显示,但不会修改盘符以及影响分区中的数据,仅仅只是在资源管理器中不再显示,可以理解为视觉上的隐藏适合在保证磁盘分区能正常使用的情况下让电脑使用者看不见某一些分区 w......
文件路径名解析出路径、盘符、扩展名和文件名
LPTSTR szfileName = new TCHAR[MAX_PATH]; GetModuleFileName(NULL, szfileName , MAX_PATH); // 获取盘符、文件名、扩展名等信息 wchar_t drive[_MAX_DRIVE];......
作者信息
我爱内核
Windows驱动开发,网站开发
好好学习,天天向上。
取消
感谢您的支持,我会继续努力的!
扫码支持
扫码打赏,你说多少就多少

打开支付宝扫一扫,即可进行扫码打赏哦

您的支持,是我们前进的动力!