;       SCCSID = @(#)d_mkdir.asm	6.1 91/02/15
;       SCCSID = @(#)d_mkdir.asm	1.5 90/01/22
; ****************************************************************************
; *									     *
; *			  IBM/Microsoft Confidential			     *
; *									     *
; *		    Copyright (c) IBM Corporation  1987, 1990		     *
; *		    Copyright (c) Microsoft Corp.  1987, 1990		     *
; *			      All Rights Reserved			     *
; *									     *
; ****************************************************************************
;***  d_mkdir.asm - API stub routine DosMkDir
;
;       Member of API library
;       Steve Salisbury & Bill Mershon
;       Copyright MicroSoft Corporation, 1986
;       18-Feb-1986
;
;       library routine for API simulator
;
;       Called from dos 2.x,3.x compatible dos 5.x applications
;
;       Special Information
;               none
;
;       Modification History
;       7-1-86 (billme): add code to return error if length of given path
;       is greater than 127 characters
;
;       06-Jan-87 (billme): Replace initial pushes and final pops
;       with calls to __api_begin and __api_end resp.  This will
;       reduce the size of FAPI and allow support for signals.
;
;
;       04-May-87 (robertc): Install hooks for DOSErrorClass Support.
;       All int 21h errors are passed through api_get_extended to get the
;       extended errorcode and to provide the class, action, and locus for
;       the dynamic error FIFO queue.
;
; @@    8-May-87 (Tarng): Check reserved dword are zeros.
;                         Check filename/pathname is in the 8.3 range.
;
;
; @@    27-Jul-87 (robertc): fix error reporting for long pathname
;
;       5-Dec-88  (klee): P3023 fix path name when removing a directory
;
;       12-12-88  (KLee): P3000 Change MAXPATHLENGTH
;
;       24-07-89  (klee): Point DCR 105.
;                         The offset error in EAOP is 4-bytes long.
;

include dos2equ.inc
INCLUDE bsedos.inc
INCLUDE basemaca.inc
INCLUDE error.inc
INCLUDE curdir.inc                      ; cpd12 p3000

        EXTRN   api_get_extended:far    ;@@ added support for DOSErrorClass
        EXTRN   _api_getvrsn:near
        EXTRN   __api_begin:near
        EXTRN   __api_end:near
        EXTRN   name_check:far          ;@@ added support for 8.3 filename
;/********************** START OF SPECIFICATIONS *********************/
;/*                                                                  */
;/* SUBROUTINE NAME: DosMkDir                                        */
;/*                                                                  */
;/* DESCRIPTIVE NAME: Dos Make Directory                             */
;/*                                                                  */
;/* FUNCTION: Creates the specified directory.                       */
;/*                                                                  */
;/*                                                                  */
;/*                                                                  */
;/* NOTES:    Real Mode Only                                         */
;/*           Simulates OS/2 call from DOS 2.x,3.x environment       */
;/*                                                                  */
;/* ENTRY POINT: DosMkDir                                            */
;/*                                                                  */
;/*    LINKAGE: Call Far                                             */
;/*                                                                  */
;/* INPUT: Stack Frame in form of:                                   */
;/*                                                                  */
;/*     PUSH@ ASCIIZ  DirName - new directory path name              */
;/*     PUSH  DWORD   Reserved - null double word                    */
;/*                                                                  */
;/*                                                                  */
;/* EXIT-NORMAL:   AX = 0                                            */
;/*                                                                  */
;/* EXIT-ERROR:    AX = Errorcode                                    */
;/*       may return error code from Dos 2.x, 3.x, OS/2              */
;/*                                                                  */
;/* EFFECTS:  AX, all other registers preserved                      */
;/*                                                                  */
;/* INTERNAL REFERENCES: none                                        */
;/*                                                                  */
;/*    ROUTINES:                                                     */
;/*                                                                  */
;/* EXTERNAL REFERENCES: none                                        */
;/*                                                                  */
;/*    ROUTINES: DosMkDir2                                           */
;/*              __api_begin                                         */
;/*              __api_end                                           */
;/*                                                                  */
;/*********************** END OF SPECIFICATIONS **********************/

;***    DOSMKDIR - stub to emulate DOSMKDIR function call
;
;       simulates DOS 5.0 call from DOS 2.x,3.x environment
;
;       errorcode = unsigned far pascal
;       DosMkDir (DirName,Reserved)
;
;       ENTRY:
;               DirName - new directory path name
;               Reserved - null double word
;
;       RETURN:
;               AX = 0 if no error, else error code (see DOS 5 spec)
;
;       EXIT:
;
;       USES:
;               AX
;
;       Pseudo Code:
;               save registers
;               use BP as pointer to stack parameters
;               load registers for int 21 call
;               execute int 21 with function 39h
;               restore registers
;               return
;
;       WARNING:
;               may return error code from Dos 2.x, 3.x (see dos manuals)
;
;       EFFECTS:
;               none
;

        title   DOSMKDIR - stub to emulate DOSMKDIR function call
;
;       EXTRN   DOSMKDIR:FAR
;
;       PUSH    @ ASCIZ Name
;       PUSH    DWORD 0
;       CALL    DOSMKDIR
;


_TEXT   segment byte public 'CODE'

        assume  CS:_TEXT,DS:NOTHING

        public  DOSMKDIR

; MAXPATHLEN      equ     128             ; 127 + end char p3000 cpd12

DataArea        equ     [BP+10]
Reserved0       equ     [BP+6]
UserCS          dw      ?
UserIP          dw      ?
userBP          dw      ?
EA_Allowed      db      0
DOSMKDIR        proc    far

; check validity of reserved words
        mov     ax,ERROR_INVALID_PARAMETER ; Prepare error code
        push    bp                      ; Set up stack frame
        mov     bp,sp
        push    bx                      ; Preserve Users BX
        mov     bx,Reserved0            ; reserved words not zeros
        or      bx,Reserved0 +2
        pop     bx                      ; Restore Users BX
        jnz     mdErr                   ; then return error

        pop     UserBp                  ; pop off the old bp
        pop     UserCS                  ; pop off the old cs
        pop     UserIP                  ; pop off the old ip
        push    Reserved0               ; Push Reserved Words
        push    Reserved0
        call    far ptr DosMkDir2       ; Call the Worker

        push    UserIP                  ; Restore Users IP
        push    UserCS                  ; Restore Users CS
        mov     bp,UserBp               ; Restore Users BP
        ret                             ; Return to User
mdErr:                                  ; Invalid reserved word exit
        pop     bp                      ; Remove bp
        ret     8                       ; Return to User and Lose Parms

DOSMKDIR        endp

Md2DataArea        equ     [BP+14]
Md2EABuf           equ     [BP+10]
Md2Reserved0       equ     [BP+6]

;/********************** START OF SPECIFICATIONS *********************/
;/*                                                                  */
;/* SUBROUTINE NAME: DosMkDir2                                       */
;/*                                                                  */
;/* DESCRIPTIVE NAME: Dos Make Directory                             */
;/*                                                                  */
;/* FUNCTION: Creates the specified directory.                       */
;/*                                                                  */
;/*                                                                  */
;/*                                                                  */
;/* NOTES:    Real Mode Only                                         */
;/*           Simulates OS/2 call from DOS 2.x,3.x environment       */
;/*                                                                  */
;/* ENTRY POINT: DosMkDir2                                           */
;/*                                                                  */
;/*    LINKAGE: Call Far                                             */
;/*                                                                  */
;/* INPUT: Stack Frame in form of:                                   */
;/*                                                                  */
;/*     PUSH@ ASCIIZ  DirName - new directory path name              */
;/*     PUSH@ OTHER   EA_Buf - Extended attribute buffer             */
;/*     PUSH  DWORD   Reserved - null double word                    */
;/*                                                                  */
;/*                                                                  */
;/* EXIT-NORMAL:   AX = 0                                            */
;/*                                                                  */
;/* EXIT-ERROR:    AX = Errorcode                                    */
;/*       may return error code from Dos 2.x, 3.x, OS/2              */
;/*                                                                  */
;/* EFFECTS:  AX, all other registers preserved                      */
;/*                                                                  */
;/* INTERNAL REFERENCES: none                                        */
;/*                                                                  */
;/*    ROUTINES:                                                     */
;/*                                                                  */
;/* EXTERNAL REFERENCES: none                                        */
;/*                                                                  */
;/*    ROUTINES: __api_begin                                         */
;/*              __api_end                                           */
;/*              name_check                                          */
;/*              api_get_extended                                    */
;/*              _api_get_version                                    */
;/*              Int 21h - CreateDir                                 */
;/*              Int 21h - Get/Set File Date/Time Extended Info      */
;/*                                                                  */
;/*********************** END OF SPECIFICATIONS **********************/

        public  DosMkDir2

DOSMKDIR2       proc    far

        call    __api_begin     ; init bp and save bp,ds,bx,cx,dx,si,di,es
                                ; required to save: bp,ds,dx,es,di,cx

        mov     EA_Allowed,0            ; Assume no EA
CheckEA:
        mov     ax,Md2EABuf             ; Is the EA pointer NULL
        or      ax,Md2EABuf+2
        jz      Md200                   ; Null pointer = No EA
; At this point we know the EABuf pointer is not Null so,
; get DOS Version to see if EABufs are allowed
        call    _api_getvrsn
        cmp     ax,0A14h                ; is version >= 10.2
        jb      EAError
        mov     EA_Allowed,1            ; yes, set flag
        jmp     Md200

EAError:
        mov     ax,Error_Invalid_Parameter
        jmp     NormalExit

Md200:
; check validity of reserved words
        mov     ax,ERROR_INVALID_PARAMETER      ;
        mov     bx, Md2Reserved0                ;reserved words not zeros
        or      bx,bx                           ;
        jnz     NormalExit                      ; then return error
        or      bx,Md2Reserved0+2               ;
        jnz     NormalExit                      ; then return error
Md2ChkPath:
        ; insure that string length is <= 127
        cld                             ; prepare for scasb 'increment'
        les     di,[Md2DataArea]        ; ES:DI <- pointer to pathname
        mov     cx,MAXPATHLEN           ; CX <- maximum path length
        xor     al,al                   ; AL <- zero (end of string char)
        repne   scasb                   ; search for end of string
        jz      mkdir1
        mov     ax,ERROR_PATH_NOT_FOUND ; set and return error
        jmp     short NormalExit        ;@@p6623

mkdir1:                                 ; proceed with directory removal
        lds     dx,[Md2DataArea]        ; DS:DX <- pointer to pathname

; verify the filename in 8.3 range
        push    si                      ;@@ save si
        mov     ah,3                    ;@@ meta char is invalid
        mov     si,dx                   ;@@ ds:si = pointer to filename
        call    name_check              ;@@ check name in 8.3 range
        pop     si                      ;@@ restor si
        jc      NormalExit              ;@@ filename is illegal

        mov     ah,D2_CreateDir
        int     21H
        jc      ErrorExit
        xor     ax,ax
; now add the EA info if it is allowed
        cmp     EA_Allowed,1
        jne     NormalExit

; Set the EA for this path
        mov     ax,(D2_GetSetFileDT shl 8) + 03 ; set info
        mov     dx,2                    ; Info level 2
        mov     bx,-1                   ; use a path
        lds     si,[Md2DataArea]        ; path name
        les     di,[Md2EABuf]           ; EABuf
        mov     cx,size EAOP            ; size = 12
        int     21h
        jc      EA2Error                ; Success
        xor     ax,ax
        jmp     NormalExit
EA2Error:
        call    api_get_extended        ; Get extended error info
        push    ax                      ; save it

        lds     dx,[Md2DataArea]        ; DS:DX <- pointer to pathname
                                        ; P3023 12/5/88 Klee
        mov     ah,D2_RemoveDir         ; remove the directory
        int     21H
        pop     ax                      ; restore the error code

        jmp     short NormalExit
ErrorExit:
        call    api_get_extended
NormalExit:

        call    __api_end       ; check sigs & restore es,di,si,dx,cx,bx,ds,bp

        ret     12      ; clear stack of entry parameters (bytes)
DOSMKDIR2       endp

_TEXT   ends

        end
