-1

我是一名 Delphi 开发人员,从未为网络软件编程过。但我需要在网络共享上找到文件的所有者。经过一番研究,我从一个新闻组(原作者:Chris Morgan)得到了这段代码片段。它基本上是一种动态加载 netware dll 并获取文件“所有者”信息的方法。请看函数GetNetwareFileOwner。

问题是,我无法直接访问网络软件共享进行测试。我每次都会向用户发送一个小型测试程序,该用户通过在网络共享上选择一个文件来测试它,然后报告结果。我在调用 NWIntScanExtenedInfo 后通过插入一个小代码获取错误代码,它失败并出现下面给出的错误代码。有什么想法可能是错的吗?

错误代码: 1) 首先,以下代码在上述调用中给出了错误 899E (INVALID_FILENAME)。文件名是英文的——那里没有特殊字符。并且通过常规文件打开对话框在共享上选择了该文件。

2) 在那之后,怀疑一个案例问题,我注释了两个 AnsiUpperCase 行以保持名称的原始大小写与文件打开对话框收到的完全一样。现在给出错误 89FF (NO_FILES_FOUND_ERROR)。

PS我用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;
4

1 回答 1

0

你确定stdcall吗?Tru cdecl 等等。此外,您还提供了有关 delphi 版本的信息。如果您使用 delphi2009 之前的版本,pchar 是一个单字节字符。但是如果你使用delphi2009或next,pchar是2字节char。所以,如果你需要一个字节的字符,你必须使用 PAnsiChar insthead。不知道netware dll参数是unicode还是ansi...

雪儿。

一个。

于 2013-11-19T10:05:48.497 回答