-1

I'm a Delphi developer and have never programmed for netware. But I need to find the owner of a file on a netware share. After some research, I got this code snippet from a newsgroup (original author: Chris Morgan). It's basically a way to dynamically load netware dll and get the "owner" information of a file. Please look at the function GetNetwareFileOwner.

The problem is, I don't have direct access to a netware share for testing. I'm sending a small test program every time to a user who tests it by selecting a file on the netware share and then reports the results. I'm getting the error code by a small code insert after the call NWIntScanExtenedInfo where it fails with the error codes given below. Any ideas what can be wrong?

Error codes: 1) At first, the following code gave error 899E (INVALID_FILENAME) on the above call. The file name was in English--no special characters there. And the file was selected on the share with a regular File Open dialog.

2) After that, suspecting a case problem, I commented the two AnsiUpperCase lines to keep the name in original case exactly as the File Open Dialog received it. This gives the error 89FF now (NO_FILES_FOUND_ERROR).

P.S. I compiled the test with Delphi 2007. May be there is a structure problem of the top structure. I haven't checked the byte length and alignment. Will do so.

// 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;

1 Answers1

0

Are you sure about stdcall? Tru cdecl and so on. Also, You done give information about delphi's version. If you use a version BEFORE delphi2009 pchar is a one-byte char. But if you use delphi2009 or next, pchar is 2 byte char. So, if you need one byte char you must use PAnsiChar insthead. I don't know if netware dll parameters are unicode or ansi...

Cher.

A.