%include "util.mac"
%include "icedump.inc"
%include "wiat.inc"
%include "win32n.inc"


global Parse_Alloc
global Parse_Free


extern sdata
extern Parser.error
extern Parser.errorMsg
extern Error_V86
extern Error_PM16
extern Error_PMR0
extern ParseExpression
extern API.oVirtualAlloc
extern API.oVirtualFree
extern API.oGetLastError
extern CheckWCRS
extern ReinforceINT3
extern wcrs


bits 32


;-------------------------------------------------------------------------------
; ALLOC <address> <size>
;-------------------------------------------------------------------------------
segment _LTEXT
Parse_Alloc:
	mov	edi,Error_V86
	mov	ebp,[dClient_EFLAGS]
	test	byte [ebp+2],2		; is client in V86 mode?
	jnz	near Parser.errorMsg

	mov	edi,Error_PM16
	mov	ebp,[dClient_CS]
	lar	eax,[ebp]		; is client 32 bit?
	bt	eax,22
	jnc	near Parser.errorMsg

	mov	edi,Error_PMR0
	test	byte [ebp],3		; is client in ring-0?
	jz	near Parser.errorMsg

	call	ParseExpression		; parse <address>
	jb	near Parser.error

	mov	ebp,[dClient_ESI]
	mov	[ebp],eax

	call	[pSkipWhiteSpace]
	jz	near Parser.error

	call	ParseExpression		; parse <size>
	jb	near Parser.error

	mov	ebp,[dClient_ECX]
	mov	[ebp],eax

	mov	ebp,[dClient_EIP]	; set client (E)IP
	mov	dword [ebp],Alloc

	call	CheckWCRS
	call	ReinforceINT3

	mov	dword [wcrs+WCRS.oINT3],Alloc.return
	mov	dword [wcrs+WCRS.valid],1

	mov	ebp,[fExecuteMoreCommands]	; set internal Winice flag to 0
	mov	byte [ebp],0

	popad
	retn


Alloc:
	push	byte PAGE_EXECUTE_READWRITE
	push	dword MEM_COMMIT | MEM_RESERVE
	push	ecx
	push	esi
	call	[API.oVirtualAlloc]
	test	eax,eax
	jnz	.ok

	call	[API.oGetLastError]

	push	eax
	mov	edi,esp
	mov	esi,.msgFail
	mov	ax,0x73			; DS_Printf
	int	0x41
	pop	eax

	jmp	short .return

.ok:
	push	eax
	mov	edi,esp
	mov	esi,.msgResult
	mov	ax,0x73			; DS_Printf
	int	0x41
	pop	eax

.return:
	int3


segment _LDATA
.msgResult:	db 'Allocated Memory Base (use with FREE): %08lX',13,10,0
.msgFail:	db 'Failed to allocate memory, Last Error Code: %08lX',13,10,0


;-------------------------------------------------------------------------------
; FREE <address>
;-------------------------------------------------------------------------------
segment _LTEXT
Parse_Free:
	mov	edi,Error_V86
	mov	ebp,[dClient_EFLAGS]
	test	byte [ebp+2],2		; is client in V86 mode?
	jnz	near Parser.errorMsg

	mov	edi,Error_PM16
	mov	ebp,[dClient_CS]
	lar	eax,[ebp]		; is client 32 bit?
	bt	eax,22
	jnc	near Parser.errorMsg

	mov	edi,Error_PMR0
	test	byte [ebp],3		; is client in ring-0?
	jz	near Parser.errorMsg

	call	ParseExpression		; parse <address>
	jb	near Parser.error

	mov	ebp,[dClient_ESI]
	mov	[ebp],eax

	mov	ebp,[dClient_EIP]	; set client (E)IP
	mov	dword [ebp],Free

	call	CheckWCRS
	call	ReinforceINT3

	mov	dword [wcrs+WCRS.oINT3],Free.return
	mov	dword [wcrs+WCRS.valid],1

	mov	ebp,[fExecuteMoreCommands]	; set internal Winice flag to 0
	mov	byte [ebp],0

	popad
	retn


Free:
	push	dword MEM_RELEASE
	push	byte 0
	push	esi
	call	[API.oVirtualFree]
	or	eax,eax
	jnz	.return

	call	[API.oGetLastError]

	push	eax
	mov	edi,esp
	mov	esi,.msgFail
	mov	ax,0x73			; DS_Printf
	int	0x41
	pop	eax

.return:
	int3


segment _LDATA
.msgFail:	db 'Failed to free memory, Last Error Code: %08lX',13,10,0
