2013-10-23 70 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.