今天想批量改WP8的SD卡里面的所有txt文件的扩展名为txtk,为了让开卷倒入看本地小说,可我那些中二意淫傻逼起点文有300多个文件,你让我手动全改了不是爆我菊花呢。。。于是去网上找了各种软件,别说更改了,连WP设备都看不到,最后找到了Total Commands,嘿,这个能看到WP设备了,也能手动改名,然后我兴高采烈的用了里面的批量重命名,结果一脸苦逼,全部失败没一个成功。。。
然后我顶不住了,绝对要自己写了。。。
WP设备连接到PC后,是显示为移动设备,资源管理器进去后右键菜单少的可怜,只有基本的文件操作,不过好歹能改名,为了知道怎么改的,OD上阵,发现是那shell32调用wpdshext的COM接口来改的,继续跟wpdshext,就发现了其调用PortableDeviceApi来改名,继续跟进去,PortableDeviceApi使用CreateFile访问USB PNP设备ID,然后发送IO控制代码,呃,好麻烦。。。按照微软的尿性,dll文件带有api的一般都有文档,跑去SDK目录搜索h文件,果然看到了一大堆PortableDeviceXXX的头文件,跑去MSDN的Device转了一下,嘿,看到个Windows Portable Devices 。。。
那如何改名呢,看下面:
1:首先我们要创建IPortableDeviceManger接口,使用CoCreateInstance;
2:然后使用IPortableDeviceManger->GetDevices接口,返回设备总数和ID,记得ID是一个字符串数组,需要你手动调用CoTaskMemFree一个个释放掉;
3:然后创建IPortableDevice接口,还是使用CoCreateInstance,再创建一个IPortableDeviceValues,也是CoCreateInstance;
4:调用IPortableDevice->Open接口,传入步骤2获得的设备ID字符串和上面创建的IPortableDeviceValues指针;
5:Open成功后,再调用IPortableDevice->Content接口,返回一个IPortableDeviceContent接口;
6:IPortableDeviceContent成功返回后,调用IPortableDeviceContent->EnumObject,传入根ID:WPD_DEVICE_OBJECT_ID,然后返回一个IEnumPortableDeviceObjectIDs接口;
7:调用IEnumPortableDeviceObjectIDs->的Next接口,传入一个LPWSTR的数组和下标,表示要一次获得多少个对象ID字符串,再传入一个DWORD指针,返回实际获得了多少个ID字符串;
8:获得的字符串是无明的ID,给IPortableDeviceContent->EnumObject继续递归枚举用,而我们需要通过字符串ID获取真正的属性,再调用IPortableDeviceContent->Properties,返回一个IPortableDeviceProperties接口,调用IPortableDeviceProperties->GetValues,传入枚举Next接口返回的字符串ID,IPortableDeviceProperties会返回一个IPortableDeviceValues接口,这就是存储一切的东西了;
9:此时我们调用IPortableDeviceValues->GetStringValue,传入WPD_OBJECT_NAME,会返回显示名称,更改就使用IPortableDeviceValue->SetStringValue,然后用IPortableDeviceProperties->SetValues设置这个IPortableDeviceValues过去,就行了,比如改名就用WPD_OBJECT_ORIGINAL_FILE_NAME。
还有很多地方要注意,比如字符串都需要自己手动释放,比如要枚举文件夹子文件夹,更改文件夹内的名称需要扯到很多ID和属性,自己看MSDN吧,这神奇的改名方式。。。