2013-10-23 34 views
-1

我是一名Delphi开发人员,并且从来没有为netware编写过程序。但我需要在netware共享上找到文件的所有者。经过一番研究后,我从一个新闻组(原作者:Chris Morgan)得到了这段代码片段。这基本上是一种动态加载netware dll并获取文件的“所有者”信息的方式。请查看GetNetwareFileOwner函数。德尔福代码来获取Netware文件的所有者不起作用

问题是,我没有直接访问netware共享进行测试。我每次发送一个小测试程序给测试它的用户,方法是在netware共享上选择一个文件,然后报告结果。在调用NWIntScanExtenedInfo之后,我通过一个小代码插入错误代码,并在下面给出的错误代码中失败。任何想法可能是错误的?

错误代码: 1)首先,下面的代码在上面的调用中给出错误899E(INVALID_FILENAME)。文件名是英文 - 没有特殊字符。然后通过常规的文件打开对话框在共享上选择文件。

2)之后,怀疑一个案例问题,我评论了两个AnsiUpperCase行以保持原来的名称与文件打开对话框收到的名称完全相同。现在给出错误89FF(NO_FILES_FOUND_ERROR)。

P.S.我使用Delphi 2007编译了测试。可能存在顶层结构的结构问题。我没有检查字节长度和对齐。会这样做。

// netware records and function definitions 
type 
    // sizeof(NW_EXT_FILE_INFO) should be 140 bytes - check byte alignment 
    NW_EXT_FILE_INFO = record 
     sequence: integer; 
     parent: integer; 
     attributes: integer; 
     uniqueID: shortint; 
     flags: shortint; 
     nameSpace: shortint; 
     nameLength: shortint; 
     name: array[0..11] of shortint; 
     creationDateAndTime: integer; 
     ownerID: integer; 
     lastArchiveDateAndTime: integer; 
     lastArchiverID: integer; 
     updateDateAndTime: integer; 
     lastUpdatorID: integer; 
     dataForkSize: integer; 
     dataForkFirstFAT: integer; 
     nextTrusteeEntry: integer; 
     reserved: array[0..35] of shortint; 
     inheritedRightsMask: word; 
     lastAccessDate: word; 
     deletedFileTime: integer; 
     deletedDateAndTime: integer; 
     deletorID: integer; 
     reserved2: array[0..15] of shortint; 
     otherForkSize: array[0..1] of integer; 
    end; 

    // functions defined in CALWIN32.DLL 
    TNWCallsInit = function(reserved1: pointer; 
     reserved2: pointer): integer; stdcall; 
    TNWCallsTerm = function(reserved: pointer): integer; stdcall; 
    TNWParseNetWarePath = function(const path: pchar; var conn: cardinal; 
     var dirhandle: cardinal; newpath: pchar): integer; stdcall; 
    TNWAllocTemporaryDirectoryHandle = function(conn: cardinal; 
     dirhandle: cardinal; const path: pchar; var newdirhandle: cardinal; 
     rightsmask: pshortint): integer; stdcall; 
    TNWDeallocateDirectoryHandle = function(conn: cardinal; 
     dirhandle: cardinal): integer; stdcall; 
    TNWIntScanExtendedInfo = function(conn: cardinal; dirhandle: cardinal; 
     attrs: shortint; iterhandle: Pinteger; const searchPattern: pchar; 
     var entryinfo: NW_EXT_FILE_INFO; augmentflag: shortint): integer; 
stdcall; 
    TNWGetObjectName = function(conn: cardinal; objID: integer; 
     objname: pchar; objtype: pword): integer; stdcall; 

const 
    FA_NORMAL = $00; 
    FA_HIDDEN = $02; 
    FA_SYSTEM = $04; 
    // return codes 
    SUCCESSFUL = $00; 
    NOT_MY_RESOURCE = $883C; 

// get file owner for Netware server file 
function GetNetwareFileOwner(const FilePath: string): string; 
var 
    hcalwin:       HINST; 
    NWCallsInit:      TNWCallsInit; 
    NWParseNetWarePath:    TNWParseNetWarePath; 
    NWAllocTemporaryDirectoryHandle: TNWAllocTemporaryDirectoryHandle; 
    NWIntScanExtendedInfo:   TNWIntScanExtendedInfo; 
    NWGetObjectName:     TNWGetObjectName; 
    NWDeallocateDirectoryHandle:  TNWDeallocateDirectoryHandle; 
    NWCallsTerm:      TNWCallsTerm; 
    hconn, 
    hdir, 
    retcode:       cardinal; 
    filedir:       string; { DOS path of parent folder 
(upper case) } 
    nwfilename:      string; { DOS filename (upper case) } 
    nwfiledir:      array[0..255] of char; { Netware path of 
parent folder } 
    rights:       shortint; 
    i:        integer; 
    entryinfo:      NW_EXT_FILE_INFO; 
    objtype:       word; 
begin 
    Result := ''; 
    // load netware client library and required functions 
    hcalwin := LoadLibrary('calwin32.dll'); 
    if hcalwin<=0 then exit; // netware client not present on PC 

    @NWCallsInit := GetProcAddress(hcalwin,'NWCallsInit'); 
    @NWParseNetWarePath := GetProcAddress(hcalwin,'NWParseNetWarePath'); 
    @NWAllocTemporaryDirectoryHandle := GetProcAddress(hcalwin, 

'NWAllocTemporaryDirectoryHandle'); 
    @NWIntScanExtendedInfo := 
GetProcAddress(hcalwin,'NWIntScanExtendedInfo'); 
    @NWGetObjectName := GetProcAddress(hcalwin,'NWGetObjectName'); 
    @NWDeallocateDirectoryHandle := GetProcAddress(hcalwin, 
             'NWDeallocateDirectoryHandle'); 
    @NWCallsTerm := GetProcAddress(hcalwin,'NWCallsTerm'); 

    // initialise netware libs 
    if NWCallsInit(nil,nil)<>SUCCESSFUL then exit; 
    try 
     filedir := AnsiUpperCase(ExtractFileDir(FilePath)); 
     retcode := NWParseNetWarePath(pchar(filedir),hconn,hdir,nwfiledir); 
     if retcode=NOT_MY_RESOURCE then exit; // local or non-netware disk 

     // get a dir handle 
     NWAllocTemporaryDirectoryHandle(hconn,0,nwfiledir,hdir,@rights); 

     // get the file info 
     i := -1; 
     nwfilename := AnsiUpperCase(ExtractFileName(FilePath)); 
     retcode := NWIntScanExtendedInfo(hconn,hdir, 
        FA_NORMAL+FA_SYSTEM+FA_HIDDEN, 
        @i,pchar(nwfilename),entryinfo,0); 

     if retcode=SUCCESSFUL then begin 
     // get file owner name from ID 
     SetLength(Result,MAX_PATH); 
     retcode := NWGetObjectName(hconn,entryinfo.ownerID, 
         pchar(Result),@objtype); 
     if retcode=SUCCESSFUL then 
      SetLength(Result,Length(Result)) // got owner 
     else SetLength(Result,0); // failed to get owner 
     end; 

     // deallocate dir handle 
     NWDeallocateDirectoryHandle(hconn,hdir); 
    finally 
     // clean up 
     NWCallsTerm(nil); 
     FreeLibrary(hcalwin); 
    end; 
end; 

回答

0

你确定关于stdcall吗? Tru cdecl等等。 另外,您完成了关于delphi版本的信息。 如果您使用的是BEFORE delphi2009的版本,则pchar是一个单字节字符。 但是,如果你使用delphi2009或其他版本,pchar是2字节字符。 所以,如果你需要一个字节的字符,你必须使用PAnsiChar insthead。 我不知道是否netware dll参数是unicode或ansi ...

Cher。

A.