2012年7月5日星期四

设备对象和符号链接及转换的应用成代码

.386
.model flat,stdcall
option casemap:none

include kernel32.inc
includelib kernel32.lib

.data?
hstdin dd ?
hstdout dd ?
x dd ?
y dword ?
buffer db 2000h dup (?)

.code
;数据定义在代码段,可使文件更小。
;若想写代码段定义的变量,请在在编译时加:/section:.text,rw
notice db "list all of existing MS-DOS device names",13,10,\
          "made by correy",13,10,\
          "QQ:112426112",13,10,\
          "Email:leguanyuan@126.com",13,10,\
          "Homepage:http://correy.webs.com",13,10,\
          "不足之处,敬请指导。",13,10,\
          "注意显示格式,可以在运行窗口的标题上右键选择属性-->布局-->里面的窗口大小或缓冲区的大小,进行改变。",13,10,0
          ;我想这也可以用编程实现。

outtitle db "按回车键退出!",13,10,0

entry db 13,10,0

start:invoke GetStdHandle,-10
mov hstdin,eax
invoke GetStdHandle,-11
mov hstdout,eax
invoke QueryDosDevice,0,addr buffer,2000h
mov x,eax
lea esi,buffer
mov edi,0
invoke WriteFile,hstdout,addr notice,sizeof notice-1,offset y,0
show:
invoke lstrlen,esi
push eax
invoke WriteFile,hstdout,esi,eax,addr y,0
invoke WriteFile,hstdout,addr entry,2,offset y,0
pop eax
inc eax
add esi,eax
add edi,eax
cmp edi,x
jne show
invoke WriteFile,hstdout,addr outtitle,sizeof outtitle-1,offset y,0
invoke ReadFile,hstdin,addr buffer,sizeof buffer,addr y,0
ret
end start 
;made at 2010.11.05

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

/*
ade by correy
made at 2014.04.15
email:kouleguan at hotmail dot com
homepage:http://correy.webs.com
*/

#include <Windows.h>


bool get_symbollink_from_devicename(IN wchar_t * device_name, OUT wchar_t * symbol_link_name)
    /*
    功能:根据设备名获取符号链接名.
    device_name:格式心形如:\Device\USBPDO-3.
    symbol_link_name的内容不可以太小,不小于MAX_PATH.
    */
{
    bool b = false;

    if (device_name == NULL || * device_name == 0 || symbol_link_name == NULL) {
        return false;
    }

    DWORD ucchMax = 0x1000;//大概一个页面的大小.
    LPTSTR buffer = (LPTSTR)HeapAlloc(GetProcessHeap(),0,ucchMax);
    int x = 0;
    while (!(x = QueryDosDevice(NULL, buffer, ucchMax / sizeof(wchar_t)))) //不除以2,第二次运行的时候出错,可能是内存越界了.注意TCHARs.
    {
        if (GetLastError() == ERROR_INSUFFICIENT_BUFFER) 
        { 
            if (buffer) {
                HeapFree(GetProcessHeap(), 0, buffer); 
                buffer = NULL;
            }

            ucchMax *= 2; //翻倍增长.

            buffer = (LPTSTR)HeapAlloc(GetProcessHeap(),0,ucchMax); 
            if (!buffer){
                return false; 
            }
            RtlZeroMemory(buffer, ucchMax);
        } else { 
            return false; 
        } 
    }

    LPTSTR buffer0 = buffer;//这个变量供释放用的.

    int s = 0;
    int i = 0;
    while (s < x)
    {
        i++;

        if (lstrlen(buffer) == 0) {
            break;//结束了.没有找到.
        }

        wchar_t d[MAX_PATH] = {0};
        QueryDosDevice(buffer,d,sizeof (d));

        int t = lstrlen(buffer);
        buffer = buffer + t + 1;

        printf("符号链接:%ws", buffer);

        wchar_t temp[MAX_PATH] = {0};
        if (!QueryDosDevice(buffer,temp,MAX_PATH / sizeof(wchar_t))) {
            break;
        }

        printf("设备名:%ws\n", temp);

        if (lstrcmpi(temp, device_name) == 0) {//注意设备在禁用的状态下是搜索不到的.
            b = true;
            lstrcpy(symbol_link_name, buffer);
        }

        s = s + t + 1;
    }

    HeapFree(GetProcessHeap(), 0, buffer0); 
    return b;
}


int main()
{
    wchar_t symbol_link_name[MAX_PATH] = {0};    
    bool b = get_symbollink_from_devicename(L"\\Device\\USBPDO-3", symbol_link_name);
    if (b) {
        MessageBox(0,L"OK",0,0);
    } else {
        MessageBox(0,L"fail",0,0);
    }

    return 0;
}

没有评论:

发表评论