/*static char *SCCSID = "@(#)fs_ffrom.c	6.3 92/01/31";*/
#define INCL_DOSERRORS
#include <os2def.h>
#include <bse.h>
#include <fsd.h>
#include <cdib.h>

#include "heap.h"
#include "api.h"
#include "const.h"
#include "chain.h"
#include "misc.h"
#include "buf.h"
#include "dir.h"
#include "find.h"
#include "storage.h"
#include "volume.h"
#include "tables.h"
#include "pb_ifs.h"
#include "pbmacros.h"
#include "lw.h"
#include "frame.h"
#include "fsdata.h"
#include "tefti.h"
#include "ea.h"
#include "codepage.h"
#include "pr_CACHE.h"
#include "pr_FIND.h"
#include "pr_DIR.h"
#include "pr_MISC.h"
#include "pr_HEAP.h"
#include "pr_DEBUG.h"


/*
 ***	FS_FINDFROMNAME - continue file search from a name
 *
 *	Use the file name to locate the continuation spot for
 *	the search.  Then call FindMatch to fill up the return
 *	buffer with matching entries.
 *
 *	HISTORY
 *	    26-May-1989 by JR (John Rogers, JohnRo@Microsoft)
 *		- DCR 259.2: changed names of macros in "frame.h".
 */

int far pascal
FS_FINDFROMNAME (
    struct fsfsi far *	pfsfsi,
    struct fsfsd far *	pfsfsd,
    PCHAR		pbData,	    /* ptr to data buffer */
    USHORT		cbData,	    /* size of data buffer */
    PUSHORT		pcMatch,    /* number of matching entries returned */
    USHORT		usLevel,    /* level of info returned */
    ULONG		ulPos,	    /* unused by Pinball */
    PCHAR		pbName,
    USHORT		usFlags)
{
    PFWORK	    pfw;	/* ptr to FWORK structure (search handle) */
    BYTE	    cbName;	/* length of name */
    PPASCALSTRING   pspName;	/* ptr to cracked name */
    USHORT	    usError;	/* return code */
    PEAOP	    peaop;	/* eaop from caller's buffer for level 3 */
    FRAME	    frm;

    frm.usHardErr = NO_ERROR;
    frm.fRecheckAddr = TRUE;

#ifdef TEFTI
    ClearCounter (0);
    StartCounter (0);
#endif

#ifdef DEBUG
    if (*pbName == '\0') {
	dprintf (__FILE__"(%d): pName (%p) is null string\n",
		 __LINE__, pbName);
	Int3 ();
    }
#endif

    if ((frm.pvol = FindPVol (pfsfsi->fsi_hVPB)) == NULL) {
	return (ERROR_INVALID_HANDLE);
    }

    pfw = (PFWORK) ((PPB_FSFSD)pfsfsd)->hfind;

    /* Allocate space and copy in the name and count byte. */

    /*
     * Get the size needed to store the name and the count byte.
     * Keep in mind that len from fstrlen doesn't include null.
     */
    cbName = (BYTE) fstrlen (pbName) + sizeof (pspName->c);

    if ((pspName = GHS(cbName,&frm)) != NULL) {
	pspName->c = cbName;
	{   UINT iCP = 0;

	    /* Code Page ID 0 means use the first one (0) */
	    if (*pcurCodePage != 0) {
		while ((paCodePageEnt [iCP].CodePageID) != *pcurCodePage) {
#ifdef DEBUG
		    if ((paCodePageEnt [iCP].bFlags & CPF_REQUIRED) != 0) {
			dprintf (__FILE__": Couldn't find current code page\n");
			Int3 ();
		    }
#endif
		    iCP++;
		}
#ifdef DEBUG
		if ((paCodePageEnt [iCP].CountryCode != 0) &&
		    (paCodePageEnt [iCP].CountryCode != usCountry)) {
		    dprintf (__FILE__": Code page matches, but country code doesn't\n");
		    Int3 ();
		}
#endif
	    }

       frm.iCP = (BYTE)iCP;     //#90495

       NameUpCase (pbName, cbName - sizeof (pspName->c),
          &paCodePageEnt [iCP], pspName->b);

	}

	/* Remove the old subdir from the find list */
	if ( pfw->psbd != NULL ) {
	    pfw->psbd->cusFinds--;
	    pfw->psbd = NULL;
	}

	/*
	 * If we are to do EA work, get a pointer to the EAOP, bump the
	 * data area pointer so we preserve the EAOP in the caller's
	 * buffer, and decrease the size of the data that is left.
	 */
	if (usLevel == 3) {
	    if (cbData >= sizeof (EAOP)) {
		peaop = (PEAOP) pbData;
		pbData += sizeof (EAOP);
		cbData -= sizeof (EAOP);
	    } else {
		usError = ERROR_BUFFER_OVERFLOW;
		goto FFromExit2;
	    }
	} else {
	    peaop = NULL;
	}

	/* map into pinball internal flag bits */
	if (usFlags == FF_GETPOS) {
	    usFlags = CFR_GETPOS;
	} else {
	    usFlags = 0;
	}

	/* remember NewNames attribute */
	if (pfw->attr_union.wordattr.usSearchAttr & ATTR_NEWNAME) {
	    usFlags |= CFR_NEWNAME;
	}

	usError = FindFromName (pspName, usLevel, usFlags,
				cbData, pbData, pfw, pcMatch, peaop, &frm);

    } else {
	usError = ERROR_NOT_ENOUGH_MEMORY;
	goto FFromExit1;
    }

FFromExit2:
    RetHeap (pspName);

FFromExit1:

#ifdef DEBUG
    VBS ();
#endif

    /* Get Hard Error (if any) */
    usError = FS_GetHardErr (usError);

#ifdef TEFTI
    StopCounter (0);
    LatchCounter (0);
    dprintf (__FILE__ ": %dus\n", Get_cntCounter (0));
#endif

    return usError;

    /* suppress warning messages */
    ulPos; pfsfsi;
}
