找回密码
 加入
搜索
查看: 2193|回复: 4

[系统综合] 请教将C编写的函数转换成AU3的代码

[复制链接]
发表于 2012-2-3 13:23:02 | 显示全部楼层 |阅读模式
这是C编写的两个函数,是用来复制文件的,如何转换成AU3的代码,请大大们看看~~~~
ULONGLONG *GetFileClusters(
                    PCHAR lpFileName,
                    ULONG ClusterSize,
                    ULONG *ClCount,
                    ULONG *FileSize
                    )
{
    HANDLE  hFile;
    ULONG   OutSize;
    ULONG   Bytes, Cls, CnCount, r;
    ULONGLONG *Clusters = NULL;
    BOOLEAN Result = FALSE;
    LARGE_INTEGER PrevVCN, Lcn;
    STARTING_VCN_INPUT_BUFFER  InBuf;
    PRETRIEVAL_POINTERS_BUFFER OutBuf;

    hFile = CreateFile(lpFileName, FILE_READ_ATTRIBUTES,
                       FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
                       NULL, OPEN_EXISTING, 0, 0);

    if (hFile != INVALID_HANDLE_VALUE)
    {
        *FileSize = GetFileSize(hFile, NULL);

        OutSize = sizeof(RETRIEVAL_POINTERS_BUFFER) + (*FileSize / ClusterSize) * sizeof(OutBuf->Extents);

        OutBuf = malloc(OutSize);

        InBuf.StartingVcn.QuadPart = 0;
               
        if (DeviceIoControl(hFile, FSCTL_GET_RETRIEVAL_POINTERS, &InBuf,
                            sizeof(InBuf), OutBuf, OutSize, &Bytes, NULL))
        {
            *ClCount = (*FileSize + ClusterSize - 1) / ClusterSize;

            Clusters = malloc(*ClCount * sizeof(ULONGLONG));

            PrevVCN = OutBuf->StartingVcn;

            for (r = 0, Cls = 0; r < OutBuf->ExtentCount; r++)
            {
                Lcn = OutBuf->Extents[r].Lcn;

                for (CnCount = (ULONG)(OutBuf->Extents[r].NextVcn.QuadPart - PrevVCN.QuadPart);
                     CnCount; CnCount--, Cls++, Lcn.QuadPart++) Clusters[Cls] = Lcn.QuadPart;

                PrevVCN = OutBuf->Extents[r].NextVcn;
            }
        }
                       
        free(OutBuf);       

        CloseHandle(hFile);
    }
    return Clusters;
}

void FileCopy(
        PCHAR lpSrcName,
        PCHAR lpDstName
        )
{
    ULONG         ClusterSize, BlockSize;
    ULONGLONG    *Clusters;
    ULONG         ClCount, FileSize, Bytes;
    HANDLE        hDrive, hFile;
    ULONG         SecPerCl, BtPerSec, r;
    PVOID         Buff;
    LARGE_INTEGER Offset;
    CHAR          Name[7];
       
    Name[0] = lpSrcName[0];
    Name[1] = ':';
    Name[2] = 0;

    GetDiskFreeSpace(Name, &SecPerCl, &BtPerSec, NULL, NULL);

    ClusterSize = SecPerCl * BtPerSec;
       
    Clusters = GetFileClusters(lpSrcName, ClusterSize, &ClCount, &FileSize);

    if (Clusters)
    {
        Name[0] = '\\';
        Name[1] = '\\';
        Name[2] = '.';
        Name[3] = '\\';
        Name[4] = lpSrcName[0];
        Name[5] = ':';
        Name[6] = 0;

        hDrive = CreateFile(Name, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, 0);

        if (hDrive != INVALID_HANDLE_VALUE)
        {
            hFile = CreateFile(lpDstName, GENERIC_WRITE, 0, NULL, CREATE_NEW, 0, 0);

            if (hFile != INVALID_HANDLE_VALUE)
            {
                Buff = malloc(ClusterSize);

                for (r = 0; r < ClCount; r++, FileSize -= BlockSize)
                {
                    Offset.QuadPart = ClusterSize * Clusters[r];

                    SetFilePointer(hDrive, Offset.LowPart, &Offset.HighPart, FILE_BEGIN);

                    ReadFile(hDrive, Buff, ClusterSize, &Bytes, NULL);

                    BlockSize = FileSize < ClusterSize ? FileSize : ClusterSize;

                    WriteFile(hFile, Buff, BlockSize, &Bytes, NULL);
                }

                free(Buff);

                CloseHandle(hFile);
            }
            CloseHandle(hDrive);
        }
        free(Clusters);
    }
}
发表于 2012-2-3 15:12:19 | 显示全部楼层
本帖最后由 netegg 于 2012-2-3 15:14 编辑

原生api,还是自己写的?如果是自己写的,自己转应该不难,如果找了段代码,就让人转,似乎欠妥吧
 楼主| 发表于 2012-2-3 15:38:30 | 显示全部楼层
本帖最后由 seeking 于 2012-2-3 15:39 编辑

回复 2# netegg
这是《使用直接硬盘访问读取文件》文章中的范例代码,俄国人写的,有不妥当的地方请指出。
我照着写了一部分了,'DeviceIoControl'调用也成功了,但返回的结果却是空的,不知道为什么。。。
Func _GetFileClusters($sFile)
        Local $ClusterSize, $hFile, $FileSize, $i, $OUTPUT_BUFFER, $INPUT_BUFFER
        $ClusterSize=_DriveGetClusterSize(_FM_PathGetDrive($sFile)&":")
        
        Local Const $FILE_READ_ATTRIBUTES=0x0080
        $hFile = _FM_CreateFile($sFile, $FILE_READ_ATTRIBUTES, BitOR($FILE_SHARE_READ,$FILE_SHARE_DELETE,$FILE_SHARE_WRITE), $OPEN_EXISTING, 0)
        If @error Then MsgBox(0,'error', 'Get File handle error:'&@error)
        
        $FileSize = _WinAPI_GetFileSizeEx($hFile)
        Local Const $FSCTL_GET_RETRIEVAL_POINTERS = _FM_CTL_CODE(0x00000009, 28, 3, 0)
        Local $tagRETRIEVAL_POINTERS_BUFFER = "dword ExtentCount;int64 StartingVcn"
        Local $tagOUTPUT_BUFFER=$tagRETRIEVAL_POINTERS_BUFFER
        For $i=1 To Ceiling($FileSize/$ClusterSize)
                $tagOUTPUT_BUFFER &= ";struct;int64 NextVcn"&$i&";int64 Lcn"&$i&";endstruct"
        Next
        $OUTPUT_BUFFER=DllStructCreate($tagOUTPUT_BUFFER)        
        
        Local $tagSTARTING_VCN_INPUT_BUFFER = "int64 StartingVcn"
        $INPUT_BUFFER=DllStructCreate($tagSTARTING_VCN_INPUT_BUFFER)
        DllStructSetData($INPUT_BUFFER, 1, 0)
        Local $iError, $Ret
        $Ret = DllCall("kernel32.dll", 'int', 'DeviceIoControl', _
                        'handle', $hFile, _
                        'dword', $FSCTL_GET_RETRIEVAL_POINTERS, _
                        'PTR', DllStructGetPtr($INPUT_BUFFER), _
                        'dword', DllStructGetSize($INPUT_BUFFER), _
                        'PTR', DllStructGetPtr($OUTPUT_BUFFER), _
                        'dword', DllStructGetSize($OUTPUT_BUFFER), _
                        'dword*', 0, _
                        'PTR', 0 _
                        )
        $iError = _WinAPI_GetLastErrorMessage()
        MsgBox(0,"DeviceIoControl", $Ret[0]&@CRLF&$iError)
        MsgBox(0,'', "ExtentCount:"&DllStructGetData($OUTPUT_BUFFER,1)&@CRLF& _
                                 "StartingVcn:"&DllStructGetData($OUTPUT_BUFFER,2)&@CRLF& _
                                 "NextVcn:"&DllStructGetData(DllStructGetData($OUTPUT_BUFFER,3),1)&@CRLF& _
                                 "Lcn:"&DllStructGetData(DllStructGetData($OUTPUT_BUFFER,3),2)&@CRLF )        
EndFunc
发表于 2012-2-3 15:56:03 | 显示全部楼层
本帖最后由 netegg 于 2012-2-3 15:58 编辑

我说的不是这个意思,原生api可以写写,如果是别人用api写的转了有什么意义呢,api的代码太多了,难道看见一个就转一个吗

况且,有不少程序员最喜欢的就是编写api,不可能看见就转的,msdn里有的是api程序源代码,难道都要转到auto来?
 楼主| 发表于 2012-2-3 20:29:20 | 显示全部楼层
回复 4# netegg

这是倒不是原生api,主要是我想学习一下,我转成的AU3代码,哪里出问题了。
试了很久都没有找到问题。
您需要登录后才可以回帖 登录 | 加入

本版积分规则

QQ|手机版|小黑屋|AUTOIT CN ( 鲁ICP备19019924号-1 )谷歌 百度

GMT+8, 2024-12-30 02:40 , Processed in 0.075173 second(s), 23 queries .

Powered by Discuz! X3.5 Licensed

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表