Loading
Russian
Polish
Mikołaj Hajduk's Homepage

Simple password generator

P
rogram SimPaGen is a simple in use, small and very flexible application for password creation. Written with FASM utility makes easier generation of safe passwords used for logging on various forums, e-mail accounts and other sites.

Simple animation presenting program SimPaGen execution:

Technical details

Created passwords consist of characters belonging to any combination of these four predefined categories:

  • letters A, ..., Z,
  • letters a, ..., z,
  • digits 0, ..., 9,
  • underscore symbol '_'
and the user-defined character set. Number of all possible non-empty character sets is equal to 2224-1 (number of all non-empty subsets of the set containing symbols with hexadecimal codes from 0x20 to 0xFF). Maximal length of the generated password is equal to 9999 characters. Created password is copied into the clipboard by pushing the button

Special hotkey WIN + F12 defined by application, generates a new password and copies it into the clipboard (also if the application window is not active). Program settings such as length of the created passwords and password character set are saved in the registry key

HKEY_CURRENT_USER\Software\SimPaGen\<program_version>

when the application ends. Application uses CryptoAPI functions from 'advapi32.dll' library in order to gain "cryptographically random" sequence of the password characters.

Source file of the application contains embedded data of the manifest and the program icons.

Program is an example of the edit fields subclassing method.

History of the project

v.2008.08.12.0 - first public release of the application.

v.2008.09.11.0 - additions and changes:

  • added button which copies password from the application edit field to the clipboard,
  • added hotkey WIN + F12 which generates new password and copies it to the clipboard (hotkey works also if application window is not active),
  • added possibility of saving actual program settings (password length and password character set) in the Windows registry,
  • simplified and corrected operations on the array which defines characteristic function of the password character set.

Source

Here you can take a look on the source file:

; Program written with FASM for the password creation. Passwords consist of characters
; belonging to any combination of these four predefined categories:
;
;	* letters A, ..., Z,
;	* letters a, ..., z,
;	* digits 0, ..., 9,
;	* underscore symbol '_'
;
; and the user-defined character set. Number of all possible non-empty character sets
; is equal to 2^224-1 (number of all non-empty subsets of the set containing symbols
; with hexadecimal codes from 0x20 to 0xFF). Maximal length of the generated password is
; equal to 9999 characters. Created password is copied into the clipboard by pushing the
; button with icon.
;
; Special hotkey WIN + F12 defined by application, generates a new password and copies
; it into the clipboard (also if the application window is not active)
;
; Program settings such as length of the created passwords and password character set
; are saved in the registry key
;
;		HKEY_CURRENT_USER\Software\SimPaGen\<program_version>
;
; when the application ends.
;
; Application uses CryptoAPI functions from 'advapi32.dll' library in order to gain
; "cryptographically random" sequence of the password characters.
;
; This source file of the application contains embedded data of the manifest and the
; program icons.
;
; Program is an example of the edit fields subclassing method.
;
; (C) Mikołaj Hajduk, 11.09.2008.
;
; Homepage:	http://mikhajduk.houa.org
; E-mail:	mikhajduk@gmail.com
;
format PE GUI 4.0

; Include the file containing all necessary FASM macros used in the program.
;
include 'win32wx.inc'

; Select the code page used to encoding the source file.
;
include '\ENCODING\utf8.inc'

; Information about the actual version of the application.
;
PROG_VERSION	equ '2008.09.11.0'


; Definition of the global data.
;
section '.data' data readable writeable

	; Strings containing names of the classes predefined in Windows system.
	;
	_edit		du 'EDIT', 0
	_button		du 'BUTTON', 0
	_static		du 'STATIC', 0

	; Strings containing names of the classes defined in the program.
	;
	_MainClass	du 'SimPaGen', 0
	_PassPanelClass	du 'PassPanel', 0
	_CharPanelClass	du 'CharPanel', 0

	; Definitions of the window classes used in the program.
	;
	MainClass	WNDCLASS 0, WindowProc, 0, 0, NULL, NULL, NULL, COLOR_BTNFACE + 1, NULL, _MainClass
	PassPanelClass	WNDCLASS 0, PassPanelProc, 0, 0, NULL, NULL, NULL, COLOR_BTNFACE + 1, NULL, _PassPanelClass
	CharPanelClass	WNDCLASS 0, CharPanelProc, 0, 0, NULL, NULL, NULL, COLOR_BTNFACE + 1, NULL, _CharPanelClass

	; Handle to the font used to print strings in the program controls.
	;
	Font		dd ?

	; Structure containing information about the processed message.
	;
	msg		MSG

	; Handle to the application module.
	;
	hInstance	dd ?

	; Handle to the password panel where passwords are created.
	;
	PassPanel	dd ?

	; Handle to the character panel where character set for the created
	; passwords is defined.
	;
	CharPanel	dd ?

	; Array which defines the characteristic function of the password character set.
	;
	CharFun		rd 7

	; Array which contains string representation of created passwords length.
	;
	PassLen		du '10'
			rb 6

	; Set of flags informing about state of the check boxes corresponding to the
	; predefined categories of characters.
	;
	Flags		dw 0


; Section containing executable code.
;
section '.code' code readable writeable executable

	start:
		; We make sure of the 'comctl32.dll' library loading. It's necessary
		; for proper work of the manifest.
		;
		invoke	InitCommonControls

		; Get the application module handle.
		;
		invoke	GetModuleHandle, 0
		test	eax, eax
		jz	error
		mov	[hInstance], eax

		invoke	LoadIcon, eax, ID_MAINICON
		test	eax, eax
		jz	error
		mov	[MainClass.hIcon], eax

		invoke	LoadCursor, 0, IDC_ARROW
		test	eax, eax
		jz	error
		mov	[MainClass.hCursor], eax

		; Register the window classes used in the program.
		;
		invoke	RegisterClass, MainClass
		test	ax, ax
		jz	error

		invoke	RegisterClass, CharPanelClass
		test	ax, ax
		jz	error

		invoke	RegisterClass, PassPanelClass
		test	ax, ax
		jz	error

		invoke	CreateWindowEx, 0, _MainClass, <"SimPaGen v.", PROG_VERSION>, WS_VISIBLE + WS_SYSMENU + WS_CAPTION + WS_MINIMIZEBOX,\
				144, 128, 300, 332, NULL, 0, [hInstance], NULL
		test	eax, eax
		jz	error

	; Message processing loop.
	;
	msg_loop:
		invoke	GetMessage, msg, NULL, 0, 0
		cmp	eax, -1
		je	error

		cmp	eax, 1
		jb	end_loop
		jne	msg_loop

		; Determine if given message is intended for any panel. If yes then
		; message is processed in order to proper reaction to TAB and cursor
		; keys pressing (selection of the panel controls).
		;
		invoke	IsDialogMessage, [PassPanel], msg
		test	eax, eax
		jnz	msg_loop

		invoke	IsDialogMessage, [CharPanel], msg
		test	eax, eax
		jnz	msg_loop

		invoke	TranslateMessage, msg
		invoke	DispatchMessage, msg
		jmp	msg_loop

	error:
		stdcall	ShowLastError, NULL

	end_loop:
		invoke	ExitProcess, [msg.wParam]


; Application window procedure.
;
proc	WindowProc, hwnd, wmsg, wparam, lparam

	locals
		Disposition	dd ?
	endl

	push	ebx esi edi

	cmp	[wmsg], WM_CREATE
	je	.wmcreate
	cmp	[wmsg], WM_DESTROY
	je	.wmdestroy

	.defwndproc:
		invoke	DefWindowProc, [hwnd], [wmsg], [wparam], [lparam]
		jmp	.finish

	.wmcreate:
		; Create the font used in labels, buttons and edit controls.
		;
		invoke	CreateFont, 16, 0, 0, 0, 0, FALSE, FALSE, FALSE,\
				DEFAULT_CHARSET, OUT_RASTER_PRECIS, CLIP_DEFAULT_PRECIS,\
				DEFAULT_QUALITY, FIXED_PITCH + FF_DONTCARE, "Tahoma"

		test	eax, eax
		jz	.failed
		mov	[Font], eax

		; Create registry key (or open it if already exists) associated with application.
		;
		lea	ebx, [Disposition]
		invoke	RegCreateKeyEx, HKEY_CURRENT_USER, .KeyName, 0, 0, REG_OPTION_NON_VOLATILE,\
					KEY_ALL_ACCESS, 0, .hKey, ebx

		test	eax, eax
		jnz	.failed

		; Check if value returned by the function 'RegCreateKeyEx' in the variable
		; 'Disposition' informs about the new registry key creation.
		;
		cmp	dword [ebx], REG_CREATED_NEW_KEY
		jne	.CreatePanels

		; If the new registry key has been created then default values (defining
		; password length and password characters set) are saved in the registry key.
		;
		.SaveStartRegValues:
			; Allocate a memory block used as a buffer for registry key values.
			;
			invoke	LocalAlloc, LMEM_ZEROINIT, 29
			test	eax, eax
			jz	.failed
			xchg	ebx, eax

			; Save the set of flags determining state of the check boxes associated
			; with the predefined categories of characters (letters A-Z and digits 0-9
			; are used by default).
			;
			mov	byte [ebx], 5			; [A-Z] + [0-9]

			invoke	RegSetValueEx, [.hKey], .FlagsRegVal, 0, REG_BINARY, ebx, 2
			test	eax, eax
			jnz	.failed

			lea	eax, [ebx + 1]			; eax := ebx + 1

			; Save the characteristic function of the password characters set (excluding
			; the predefined categories of characters).
			;
			invoke	RegSetValueEx, [.hKey], .CharFunRegVal, 0, REG_BINARY, eax, 28
			test	eax, eax
			jnz	.failed

			; Free a memory block used as a buffer.
			;
			invoke	LocalFree, ebx
			test	eax, eax
			jnz	.failed

			; Save string defining default password length.
			;
			invoke	RegSetValueEx, [.hKey], .PassLenRegVal, 0, REG_SZ, PassLen, 10
			test	eax, eax
			jnz	.failed

		.CreatePanels:

			; Create the password panel where passwords are generated.
			;
			invoke	CreateWindowEx, NULL,\
					_PassPanelClass, 0,\
					WS_VISIBLE + WS_CHILD,\
					15, 10, 265, 172, [hwnd], 0, [hInstance], NULL

			test	eax, eax
			jz	.failed
			mov	[PassPanel], eax

			; Create the character panel where we define the character set for
			; created passwords.
			;
			invoke	CreateWindowEx, NULL,\
					_CharPanelClass, 0,\
					WS_VISIBLE + WS_CHILD,\
					15, 192, 265, 95, [hwnd], 0, [hInstance], NULL

			test	eax, eax
			jz	.failed
			mov	[CharPanel], eax

			; Load the characteristic function of the password characters set
			; from the registry key associated with application.
			;
			invoke	RegQueryValueEx, [.hKey], .CharFunRegVal, 0, 0, CharFun, .CharFunBufSize
			test	eax, eax
			jnz	.failed

			; Load the string representation of the password length.
			;
			invoke	RegQueryValueEx, [.hKey], .PassLenRegVal, 0, 0, PassLen, .PassLenBufSize
			test	eax, eax
			jnz	.failed

			; Copy this string into the 'ID_PASSLEN' edit field.
			;
			invoke	SendDlgItemMessage, [PassPanel], ID_PASSLEN, WM_SETTEXT, 0, PassLen

			; Allocate a memory block for the user-defined character set.
			;
			invoke	LocalAlloc, LMEM_ZEROINIT, 450
			test	eax, eax
			jz	.failed
			xchg	edi, eax
			mov	esi, edi

			; Loop for the conversion of the characteristic function into the Unicode
			; string consisting of user-defined characters.
			;
			mov	eax, 31
			xor	ebx, ebx

			.CreateOtherLoop:
				inc	al

				bt	[CharFun - 4], eax
				setc	bl			; CharTab[x] := al
				mov	byte [edi], al		; x := x + 2*CharFun[eax - 32]
				adc	edi, ebx

				test	al, al
				jnz	.CreateOtherLoop

			; Copy this string into the 'ID_PASSCHARS' edit field.
			;
			invoke	SendDlgItemMessage, [CharPanel], ID_PASSCHARS, WM_SETTEXT, 0, esi

			; Load from the registry key the set of flags determining state of the check
			; boxes associated with predefined categories of the characters.
			;
			invoke	RegQueryValueEx, [.hKey], .FlagsRegVal, 0, 0, esi, .FlagsBufSize
			test	eax, eax
			jnz	.failed

			movzx	ebx, word [esi]

			; In dependence of the flag values set the state of the check boxes.
			;
			.CheckBox_AZ:
				bt	ebx, 0
				jnc	.CheckBox_az

				invoke	SendDlgItemMessage, [CharPanel], ID_CHKBOX1, BM_CLICK, 0, 0

			.CheckBox_az:
				bt	ebx, 1
				jnc	.CheckBox_09

				invoke	SendDlgItemMessage, [CharPanel], ID_CHKBOX2, BM_CLICK, 0, 0

			.CheckBox_09:
				bt	ebx, 2
				jnc	.CheckBox__

				invoke	SendDlgItemMessage, [CharPanel], ID_CHKBOX3, BM_CLICK, 0, 0

			.CheckBox__:
				bt	ebx, 3
				jnc	.FreeMem

				invoke	SendDlgItemMessage, [CharPanel], ID_CHKBOX4, BM_CLICK, 0, 0

			.FreeMem:
				; Free a memory block where the user-defined characters were stored.
				;
				invoke	LocalFree, esi
				test	eax, eax
				jnz	.failed

		; Simulation of pressing the 'Create' button in order to create
		; an exemplary password.
		;
		invoke	SendDlgItemMessage, [PassPanel], ID_GENBTN, BM_CLICK, 0, 0

		xor	eax, eax
		jmp	.finish

	.failed:
		stdcall	ShowLastError, [hwnd]
		or	eax, -1
		jmp	.finish

	.wmdestroy:
		;
		; Save the program settings in the registry key associated with
		; the application.
		;

		; Load to the 'CharFun' array the characteristic function of the password
		; characters set.
		;
		invoke	SendMessage, [CharPanel], WM_GETCHARSET, 0, 0

		; In dependency of the flag values some predefined categories of the
		; characters are excluded from the characteristic function.
		;
		movzx	ebx, [Flags]

		.Modify_AZ:
			bt	ebx, 0
			jnc	.Modify_az

			xor	[CharFun + 4], 07FFFFFEh
		.Modify_az:
			bt	ebx, 1
			jnc	.Modify_09

			xor	[CharFun + 8], 07FFFFFEh
		.Modify_09:
			bt	ebx, 2
			jnc	.Modify__

			xor	[CharFun], 03FF0000h
		.Modify__:
			bt	ebx, 3
			jnc	.SaveRegKeyVals

			btr	dword [CharFun + 4], 31

		; Save the string representation of password length, the modified characteristic
		; function and set of the flags in the registry key.
		;
		.SaveRegKeyVals:

			invoke	RegSetValueEx, [.hKey], .CharFunRegVal, 0, REG_BINARY, CharFun, 28
			test	eax, eax
			jnz	.failed

			invoke	SendDlgItemMessage, [PassPanel], ID_PASSLEN, WM_GETTEXT, 5, PassLen

			invoke	RegSetValueEx, [.hKey], .PassLenRegVal, 0, REG_SZ, PassLen, 10
			test	eax, eax
			jnz	.failed

			invoke	RegSetValueEx, [.hKey], .FlagsRegVal, 0, REG_BINARY, Flags, 2
			test	eax, eax
			jnz	.failed

		; Close the registry key associated with the application.
		;
		invoke	RegCloseKey, [.hKey]
		test	eax, eax
		jnz	.failed

		; Destroy the previously created font.
		;
		invoke	DeleteObject, [Font]
		test	eax, eax
		jz	.failed

		invoke	PostQuitMessage, 0
		xor	eax, eax

	.finish:
		pop	edi esi ebx

		ret

	align 4

	; Variables used for operations on the registry key.
	;
	.CharFunBufSize	dd 28
	.PassLenBufSize	dd 10
	.FlagsBufSize	dd 2

	.hKey		dd ?

	.KeyName	du 'Software\SimPaGen\', PROG_VERSION, 0
	.CharFunRegVal	du 'CharFun', 0
	.PassLenRegVal	du 'PassLen', 0
	.FlagsRegVal	du 'Flags', 0

endp


; Password panel window procedure.
;
proc	PassPanelProc, hwnd, wmsg, wparam, lparam

	locals	
		Password	dd ?
		PassLen		dd ?
		CharTabLen	dd ?
	endl

	; Cryptographic Service Provider's type used in application for
	; generation the random sequence of the password characters.
	;
	PROV_RSA_FULL	= 1

	; Definition of constants equal to the identifiers of the panel
	; controls.
	;
	ID_GENBTN	= 101
	ID_CLIPBTN	= 102

	ID_PASSEDIT	= 201
	ID_PASSLEN	= 202

	; Hotkey WIN + F12 identifier.
	;
	ID_HOTKEY	= 1

	; Definition of the user messages used for communication with the
	; program edit fields.
	;
	; Constants are defined as WM_USER + 2 in order to avoid possible
	; conflicts with the messages DM_GETDEFID and DM_SETDEFID equal to
	; WM_USER and WM_USER + 1 respectively which could be sent by the
	; 'IsDialogMessage' function. 
	;
	WM_GETPASSLEN	= WM_USER + 2
	WM_GETCHARSET	= WM_USER + 2

	push	ebx ecx edx esi edi

	cmp	[wmsg], WM_CREATE
	je	.wmcreate
	cmp	[wmsg], WM_COMMAND
	je	.wmcommand
	cmp	[wmsg], WM_HOTKEY
	je	.wmhotkey
	cmp	[wmsg], WM_DESTROY
	je	.wmdestroy

	.defwndproc:
		invoke	DefWindowProc, [hwnd], [wmsg], [wparam], [lparam]
		jmp	.finish

	.wmcreate:
		; Get the Cryptographic Service Provider handle which is assigned
		; to the '.hProv' local variable.
		;
		invoke	CryptAcquireContext, .hProv, NULL, NULL, PROV_RSA_FULL, 0
		test	eax, eax
		jz	.failed

		invoke	CreateWindowEx, NULL,\
				_button, 0,\
				WS_VISIBLE + WS_CHILD + BS_GROUPBOX,\
				0, 0, 265, 172, [hwnd], 0, [hInstance], NULL

		test	eax, eax
		jz	.failed
		xchg	ebx, eax

		invoke	SendMessage, ebx, WM_SETFONT, [Font], FALSE

		invoke	SetWindowText, ebx, "Password"
		test	eax, eax
		jz	.failed

		invoke	CreateWindowEx, WS_EX_CLIENTEDGE,\
				_edit, 0,\
				WS_VISIBLE + WS_CHILD + WS_VSCROLL + ES_READONLY + ES_AUTOVSCROLL + ES_MULTILINE,\
				15, 25, 235, 80, [hwnd], ID_PASSEDIT, [hInstance], NULL

		test	eax, eax
		jz	.failed

		invoke	SendMessage, eax, WM_SETFONT, [Font], FALSE

		invoke	CreateWindowEx, NULL,\
				_static, 0,\
				WS_VISIBLE + WS_CHILD + SS_RIGHT,\
				15, 128, 50, 20, [hwnd], 0, [hInstance], NULL

		test	eax, eax
		jz	.failed
		xchg	ebx, eax

		invoke	SendMessage, ebx, WM_SETFONT, [Font], FALSE

		invoke	SetWindowText, ebx, "Length:"
		test	eax, eax
		jz	.failed

		invoke	CreateWindowEx, WS_EX_CLIENTEDGE,\
				_edit, 0,\
				WS_VISIBLE + WS_CHILD + ES_RIGHT + WS_TABSTOP,\
				70, 128, 50, 20, [hwnd], ID_PASSLEN, [hInstance], NULL

		test	eax, eax
		jz	.failed
		xchg	ebx, eax

		; Exchange default 'ID_PASSLEN' edit field procedure to the defined in the program
		;
		invoke	SetWindowLong, ebx, GWL_WNDPROC, PassLenEditProc
		test	eax, eax
		jz	.failed
		mov	[PassLenEditProc.OldWndProc], eax

		; Maximal length of the input text is set to 4 characters.
		;
		invoke	SendMessage, ebx, EM_SETLIMITTEXT, 4, 0

		invoke	SendMessage, ebx, WM_SETFONT, [Font], FALSE

		invoke	CreateWindowEx, NULL,\
				_button, 0,\
				WS_VISIBLE + WS_CHILD + WS_TABSTOP + BS_ICON,\
				133, 120, 36, 36, [hwnd], ID_CLIPBTN, [hInstance], NULL

		test	eax, eax
		jz	.failed

		; Load an icon and set it on the button used for copying generated passwords
		; to the clipboard.
		;
		invoke	LoadIcon, [hInstance], ID_COPYICON
		test	eax, eax
		jz	.failed

		invoke	SendDlgItemMessage, [hwnd], ID_CLIPBTN, BM_SETIMAGE, IMAGE_ICON, eax

		invoke	CreateWindowEx, NULL,\
				_button, 0,\
				WS_VISIBLE + WS_CHILD + WS_TABSTOP + BS_DEFPUSHBUTTON,\
				180, 119, 70, 38, [hwnd], ID_GENBTN, [hInstance], NULL

		test	eax, eax
		jz	.failed
		xchg	ebx, eax

		invoke	SendMessage, ebx, WM_SETFONT, [Font], FALSE

		invoke	SetWindowText, ebx, "Create"
		test	eax, eax
		jz	.failed

		; Allocate the memory block for the character set used for password
		; creation.
		;
		invoke	LocalAlloc, LMEM_ZEROINIT, 224
		test	eax, eax
		jz	.failed
		mov	[.CharTab], eax

		; Register the WIN + F12 hot key and associate it with the application window.
		;
		invoke	RegisterHotKey, [hwnd], ID_HOTKEY, MOD_WIN, VK_F12
		test	eax, eax
		jz	.failed

		xor	eax, eax
		jmp	.finish

	.failed:
		stdcall	ShowLastError, [hwnd]
		or	eax, -1
		jmp	.finish

	.wmcommand:
		mov	eax, [wparam]
		and	eax, 0FFFFh
		cmp	eax, ID_CLIPBTN
		je	.copy
		cmp	eax, ID_GENBTN
		jne	.defwndproc

	; Actions performed if the 'Create' button is hit.
	;
	.GenBtn:

		; Send the user message to the 'ID_PASSLEN' edit field in order to determine
		; length of the generated password.
		;
		invoke	SendDlgItemMessage, [hwnd], ID_PASSLEN, WM_GETPASSLEN, 0, 0
		test	eax, eax
		jz	.clear
		mov	[PassLen], eax

		; Send the user message to the character panel in order to determine user
		; defined character set.
		;
		invoke	SendMessage, [CharPanel], WM_GETCHARSET, 0, 0

		; Loop for transformation the characteristic function of the password character set
		; into the array of symbols for created passwords.
		;
		mov	edi, [.CharTab]
		mov	eax, 31

		.FillCharTabLoop:
			inc	al

			bt	[CharFun - 4], eax
			mov	byte [edi], al		; CharTab[x] := al
			adc	edi, 0			; x := x + CharFun[eax - 32]

			test	al, al
			jnz	.FillCharTabLoop

		; Determine length of the character array.
		;
		sub	edi, [.CharTab]

		test	edi, edi
		jz	.clear

		mov	[CharTabLen], edi

		; Transform the password length into the number of bytes of the memory
		; block needed for the created password.
		;
		mov	ebx, [PassLen]
		shl	ebx, 1
		mov	eax, ebx
		add	eax, 2

		; Allocate the memory block for the generated password.
		;
		invoke	LocalAlloc, LMEM_ZEROINIT, eax
		test	eax, eax
		jz	.failed

		mov	[Password], eax

		; Fill the allocated buffer with random bytes.
		;
		invoke	CryptGenRandom, [.hProv], ebx, eax
		test	eax, eax
		jz	.failed

		; Loop for transformation of the generated password bytes into the symbols
		; from the defined character set.
		;
		mov	ecx, [PassLen]
		mov	esi, [Password]
		mov	edi, esi
		mov	ebx, [.CharTab]

		cld

		.GenPasswordLoop:
			xor	edx, edx
			lodsw				;
			div	[CharTabLen]		;
			movzx	ax, byte [ebx + edx]	; Password[x] := CharTab[Password[x] mod CharTabLen]
			stosw				;
			loop	.GenPasswordLoop

		; Show the generated password in the 'ID_PASSEDIT' edit field.
		;
		invoke	SendDlgItemMessage, [hwnd], ID_PASSEDIT, WM_SETTEXT, 0, [Password]

		; Free the memory block allocated as a buffer for the generated password.
		;
		invoke	LocalFree, [Password]
		test	eax, eax
		jnz	.failed

		jmp	.finish

	; Operations performed if the WIN + F12 hotkey is pressed.
	;
	.wmhotkey:
		cmp	[wparam], ID_HOTKEY
		jne	.finish

		; New password creation.
		;
		invoke	SendDlgItemMessage, [hwnd], ID_GENBTN, BM_CLICK, 0, 0

	; Copy the password if the button with icon was pressed or the hotkey WIN + F12 was used.
	;
	.copy:
		; Determine length of the password in characters and calculate number
		; of bytes needed for the copied password.
		;
		invoke	SendDlgItemMessage, [hwnd], ID_PASSEDIT, WM_GETTEXTLENGTH, 0, 0
		inc	eax
		mov	ebx, eax
		shl	eax, 1

		; Allocate a memory block for the copied password.
		;
		invoke	GlobalAlloc, GHND + GMEM_DDESHARE, eax		; GHND = GMEM_MOVEABLE + GMEM_ZEROINIT
		test	eax, eax
		jz	.failed

		; Lock a memory block and return a pointer to its first byte.
		;
		invoke	GlobalLock, eax
		test	eax, eax
		jz	.failed
		xchg	esi, eax

		; Open the clipboard and prevent other application from modifying clipboard
		; content.
		;
		invoke	OpenClipboard, [hwnd]
		test	eax, eax
		jz	.failed

		; Clean clipboard, free all handles to data placed in there and associate
		; the clipboard with the application window.
		;
		invoke	EmptyClipboard
		test	eax, eax
		jz	.failed

		; Copy the password to the given buffer.
		;
		invoke	SendDlgItemMessage, [hwnd], ID_PASSEDIT, WM_GETTEXT, ebx, esi

		; Place the password on the clipboard in the Unicode format.
		;
		invoke	SetClipboardData, CF_UNICODETEXT, esi
		test	eax, eax
		jz	.failed

		; Unlock the memory block used as a buffer for the copied password.
		;
		invoke	GlobalUnlock, esi
		test	eax, eax
		jz	.failed

		; Close the clipboard and enable other applications to access this.
		;
		invoke	CloseClipboard
		test	eax, eax
		jz	.failed

		jmp	.finish

	; Clear the 'ID_PASSEDIT' edit field if the character set is empty or length of the password
	; is equal to 0.
	;
	.clear:
		invoke	SendDlgItemMessage, [hwnd], ID_PASSEDIT, WM_SETTEXT, 0, 0
		jmp	.finish

	.wmdestroy:
		; Free the hotkey WIN + F12 associated with this window.
		;
		invoke	UnregisterHotKey, [hwnd], ID_HOTKEY
		test	eax, eax
		jz	.failed

		; Free the memory block allocated for the character array.
		;
		invoke	LocalFree, [.CharTab]
		test	eax, eax
		jnz	.failed

		; Release the handle to the Cryptographic Service Provider.
		;
		invoke	CryptReleaseContext, [.hProv], 0
		test	eax, eax
		jz	.failed

		xor	eax, eax

	.finish:
		pop	edi esi edx ecx ebx
		ret

	align 4

	; Handle to the character array.
	;
	.CharTab	dd ?

	; Handle to the Cryptographic Service Provider.
	;
	.hProv		dd ?
endp


; New window procedure of the 'ID_PASSLEN' edit field which allows to determine
; length of the generated password.
;
proc	PassLenEditProc, hwnd, wmsg, wparam, lparam

	cmp	[wmsg], WM_CHAR
	je	.wmchar
	cmp	[wmsg], WM_GETPASSLEN
	je	.wmuser
	cmp	[wmsg], WM_PASTE	; Block any possibility of pasting
	je	.finish			; the text into the edit field.

	.defwndproc:
		invoke	CallWindowProc, [.OldWndProc], [hwnd], [wmsg], [wparam], [lparam]
		jmp	.finish

	; Edit field accepts only the '0', ..., '9' and 'backspace' characters.
	;
	.wmchar:
		mov	eax, [wparam]

		cmp	eax, VK_BACK
		je	.defwndproc

		cmp	eax, '0'
		jb	.finish
		cmp	eax, '9'
		ja	.finish

		jmp	.defwndproc

	; If edit field received WM_GETPASSLEN message then numerical value of the stored
	; sequence of the decimal digits is calculated. Result value is returned in the eax
	; register to the procedure which send user message.
	;
	.wmuser:
		push	ebx esi

		; Get edit field content.
		;
		lea	esi, [PassLen]
		invoke	SendMessage, [hwnd], WM_GETTEXT, 5, esi

		; Loop for calculation numerical value of the sequence of the decimal
		; digits.
		;
		xor	eax, eax
		xor	ebx, ebx

		cld

		.Loop:
			lodsw

			test	eax, eax
			jz	.LoopEnd

			; ebx := 10*ebx + (eax - '0')
			;
			lea	ebx, [ebx + 4*ebx]	; ebx := ebx + 4*ebx = 5*ebx
			shl	ebx, 1			; ebx := 2*ebx
			sub	al, '0'			;
			add	ebx, eax		; ebx := ebx + (eax - '0')

			jmp	.Loop

		.LoopEnd:
			xchg	eax, ebx

		pop	esi ebx

	.finish:
		ret

	align 4

	; Handle to the old (default) edit field procedure.
	;
	.OldWndProc	dd ?
endp


; Window procedure of the character panel where we define the character set
; for the created passwords.
;
proc	CharPanelProc, hwnd, wmsg, wparam, lparam

	; Definitions of constants equal to the identifiers of the panel
	; controls.
	;
	ID_CHKBOX1	= 1
	ID_CHKBOX2	= 2
	ID_CHKBOX3	= 3
	ID_CHKBOX4	= 4

	ID_PASSCHARS	= 101

	push	ebx

	cmp	[wmsg], WM_CREATE
	je	.wmcreate
	cmp	[wmsg], WM_COMMAND
	je	.wmcommand
	cmp	[wmsg], WM_GETCHARSET
	je	.wmuser
	cmp	[wmsg], WM_DESTROY
	je	.wmdestroy

	.defwndproc:
		invoke	DefWindowProc, [hwnd], [wmsg], [wparam], [lparam]
		jmp	.finish

	.wmcreate:
		invoke	CreateWindowEx, NULL,\
				_button, 0,\
				WS_VISIBLE + WS_CHILD + BS_GROUPBOX,\
				0, 0, 265, 95, [hwnd], 0, [hInstance], NULL

		test	eax, eax
		jz	.failed
		xchg	ebx, eax

		invoke	SendMessage, ebx, WM_SETFONT, [Font], FALSE

		invoke	SetWindowText, ebx, "Used chars"
		test	eax, eax
		jz	.failed

		invoke	CreateWindowEx, NULL,\
				_button, 0,\
				WS_VISIBLE + WS_CHILD + BS_AUTOCHECKBOX + WS_TABSTOP,\
				27, 25, 40, 17, [hwnd], ID_CHKBOX1, [hInstance], NULL

		test	eax, eax
		jz	.failed
		xchg	ebx, eax

		invoke	SendMessage, ebx, WM_SETFONT, [Font], FALSE

		invoke	SetWindowText, ebx, "A-Z"
		test	eax, eax
		jz	.failed

		invoke	CreateWindowEx, NULL,\
				_button, 0,\
				WS_VISIBLE + WS_CHILD + BS_AUTOCHECKBOX + WS_TABSTOP,\
				87, 25, 40, 17, [hwnd], ID_CHKBOX2, [hInstance], NULL

		test	eax, eax
		jz	.failed
		xchg	ebx, eax

		invoke	SendMessage, ebx, WM_SETFONT, [Font], FALSE

		invoke	SetWindowText, ebx, "a-z"
		test	eax, eax
		jz	.failed

		invoke	CreateWindowEx, NULL,\
				_button, 0,\
				WS_VISIBLE + WS_CHILD + BS_AUTOCHECKBOX + WS_TABSTOP,\
				147, 25, 40, 17, [hwnd], ID_CHKBOX3, [hInstance], NULL

		test	eax, eax
		jz	.failed
		xchg	ebx, eax

		invoke	SendMessage, ebx, WM_SETFONT, [Font], FALSE

		invoke	SetWindowText, ebx, "0-9"
		test	eax, eax
		jz	.failed

		invoke	CreateWindowEx, NULL,\
				_button, 0,\
				WS_VISIBLE + WS_CHILD + BS_AUTOCHECKBOX + WS_TABSTOP,\
				207, 25, 40, 17, [hwnd], ID_CHKBOX4, [hInstance], NULL

		test	eax, eax
		jz	.failed
		xchg	ebx, eax

		invoke	SendMessage, ebx, WM_SETFONT, [Font], FALSE

		invoke	SetWindowText, ebx, "_"
		test	eax, eax
		jz	.failed

		invoke	CreateWindowEx, NULL,\
				_static, 0,\
				WS_VISIBLE + WS_CHILD + SS_RIGHT,\
				27, 60, 50, 20, [hwnd], 0, [hInstance], NULL

		test	eax, eax
		jz	.failed
		xchg	ebx, eax

		invoke	SendMessage, ebx, WM_SETFONT, [Font], FALSE

		invoke	SetWindowText, ebx, "Other:"
		test	eax, eax
		jz	.failed

		invoke	CreateWindowEx, WS_EX_CLIENTEDGE,\
				_edit, 0,\
				WS_VISIBLE + WS_CHILD + ES_AUTOHSCROLL + WS_TABSTOP,\
				82, 60, 155, 20, [hwnd], ID_PASSCHARS, [hInstance], NULL

		test	eax, eax
		jz	.failed
		xchg	ebx, eax

		invoke	SendMessage, ebx, WM_SETFONT, [Font], FALSE

		; Exchange default window procedure of 'ID_PASSCHARS' edit field to the new
		; procedure defined in the program.
		;
		invoke	SetWindowLong, ebx, GWL_WNDPROC, PassCharsEditProc
		test	eax, eax
		jz	.failed
		mov	[PassCharsEditProc.OldWndProc], eax

		xor	eax, eax
		jmp	.finish

	.failed:
		stdcall	ShowLastError, [hwnd]
		or	eax, -1
		jmp	.finish

	; If received message applies to any check box, then value of the proper flag
	; is changed.
	;
	.wmcommand:
		mov	eax, [wparam]
		and	eax, 0FFFFh
		jz	.defwndproc

		cmp	eax, ID_CHKBOX4
		ja	.defwndproc

		dec	eax
		btc	[Flags], ax

		jmp	.defwndproc

	; If panel received WM_GETCHARSET message then it transmits the same message
	; to the 'ID_PASSCHARS' edit field in order to add symbols defined by the user
	; to the character set.
	;
	.wmuser:
		invoke	SendDlgItemMessage, [hwnd], ID_PASSCHARS, WM_GETCHARSET, 0, 0
		jmp	.finish

	.wmdestroy:
		xor	eax, eax

	.finish:
		pop	ebx
		ret

endp


; New window procedure of the 'ID_PASSCHARS' edit field which allows to determine
; the user defined character set.
;
proc	PassCharsEditProc, hwnd, wmsg, wparam, lparam

	locals
		Buffer	dd ?
	endl

	cmp	[wmsg], WM_CHAR
	je	.wmchar
	cmp	[wmsg], WM_GETCHARSET
	je	.wmuser
	cmp	[wmsg], WM_PASTE	; Block any possibility of pasting
	je	.finish			; the text into the edit field.

	.defwndproc:
		invoke	CallWindowProc, [.OldWndProc], [hwnd], [wmsg], [wparam], [lparam]
		jmp	.finish

	; Edit field accepts only characters with hex codes from 20h to FFh and the 'backspace'
	; character.
	;
	.wmchar:
		mov	eax, [wparam]

		cmp	eax, VK_BACK
		je	.defwndproc

		cmp	eax, 20h
		jb	.finish
		cmp	ax, 0FFh
		ja	.finish

		jmp	.defwndproc

	.failed:
		stdcall	ShowLastError, [hwnd]
		or	eax, -1
		jmp	.finish

	; If the edit field received the WM_GETCHARSET message then the characteristic
	; function of the character set is completed with information about the user
	; defined symbols.
	;
	.wmuser:
		push	ebx ecx esi edi

		; Fill with zeros the array which defines characteristic function
		; of character set.
		;
		xor	eax, eax
		mov	ecx, 7
		mov	edi, CharFun
		cld
		rep	stosd

		; Copy an information about the state of check boxes to the ebx register.
		;
		movzx	ebx, [Flags]

		; If the flag corresponding to the some check box is set, then the characteristic
		; function is completed with the proper predefined category of symbols.
		;
		.Check_AZ:
			bt	ebx, 0
			jnc	.Check_az

			or	[CharFun + 4], 07FFFFFEh
		.Check_az:
			bt	ebx, 1
			jnc	.Check_09

			or	[CharFun + 8], 07FFFFFEh
		.Check_09:
			bt	ebx, 2
			jnc	.Check__

			or	[CharFun], 03FF0000h
		.Check__:
			bt	ebx, 3
			jnc	.OtherChars

			bts	dword [CharFun + 4], 31

		; Completion of the characteristic function of the character set
		; with user-defined symbols. 
		;
		.OtherChars:
			; Get the text length stored in the edit field.
			;
			invoke	SendMessage, [hwnd], WM_GETTEXTLENGTH, 0, 0
			inc	eax
			mov	ebx, eax
			shl	eax, 1

			; Allocation of the memory block for the text get from the edit field.
			;
			invoke	LocalAlloc, LMEM_ZEROINIT, eax
			test	eax, eax
			jz	.failed

			mov	[Buffer], eax

			; Place the content of the edit field in the reserved buffer.
			;
			invoke	SendMessage, [hwnd], WM_GETTEXT, ebx, eax

			; Loop in which we set bits adequate to user-defined chars in the array
			; representing characteristic function of the password character set.
			;
			xor	eax, eax
			mov	esi, [Buffer]

			cld

			.Loop:
				lodsw

				test	eax, eax
				jz	.LoopEnd

				bts	[CharFun - 4], eax	; CharFun[eax - 32] := 1

				jmp	.Loop

			.LoopEnd:
				; Free the memory block allocated for the text get from the edit field.
				;
				invoke	LocalFree, [Buffer]
				test	eax, eax
				jnz	.failed

		pop	edi esi ecx ebx

	.finish:
		ret

	align 4

	; Handle to the old (default) edit field procedure.
	;
	.OldWndProc	dd ?
endp


; Procedure used to show message box with the information about the last error which occurred
; during the program execution.
;
proc	ShowLastError, hwnd

	locals
		Buffer dd ?
	endl

	push	ebx

	invoke	GetLastError

	lea	ebx, [Buffer]
	invoke	FormatMessage, FORMAT_MESSAGE_ALLOCATE_BUFFER + FORMAT_MESSAGE_FROM_SYSTEM, 0, eax, LANG_NEUTRAL, ebx, 0, 0
	invoke	MessageBox, [hwnd], [Buffer], NULL, MB_ICONERROR + MB_OK
	invoke	LocalFree, [Buffer]

	pop	ebx

	ret
endp

.end start


; Section containing definitions of the application resources.
;
section '.rsrc' resource data readable

	RT_MANIFEST	= 24
	ID_MANIFEST	= 1

	ID_MAINICON	= 1
	ID_COPYICON	= 2

	directory	RT_ICON, icons,\
			RT_GROUP_ICON, icon_groups,\
			RT_VERSION, versions,\
			RT_MANIFEST, manifest

	resource	icons,\
			1, LANG_NEUTRAL, main_icon_data,\
			2, LANG_NEUTRAL, copy_icon_data

	resource	icon_groups,\
			ID_MAINICON, LANG_NEUTRAL, main_icon_grp_data,\
			ID_COPYICON, LANG_NEUTRAL, copy_icon_grp_data

	resource	versions,\
			1, LANG_NEUTRAL, version

	resource	manifest,\
			ID_MANIFEST, LANG_NEUTRAL, man

	versioninfo	version, VOS__WINDOWS32, VFT_APP, VFT2_UNKNOWN, LANG_ENGLISH + SUBLANG_DEFAULT, 0,\
			'FileDescription', 'Simple password generator.',\
			'LegalCopyright', '(C) Mikołaj Hajduk, 2008',\
			'FileVersion', PROG_VERSION,\
			'ProductVersion', PROG_VERSION,\
			'OriginalFilename', 'SimPaGen.exe'

	; Data of the program main icon embedded directly into the source file.
	;
	main_icon_data	dd RVA main_idata, 0x2E8, 0, 0

	main_idata	db	0x28,	0x0,	0x0,	0x0,	0x20,	0x0,	0x0,	0x0
			db	0x40,	0x0,	0x0,	0x0,	0x1,	0x0,	0x4,	0x0
			db	0x0,	0x0,	0x0,	0x0,	0x0,	0x0,	0x0,	0x0
			db	0x0,	0x0,	0x0,	0x0,	0x0,	0x0,	0x0,	0x0
			db	0x0,	0x0,	0x0,	0x0,	0x0,	0x0,	0x0,	0x0
			db	0x0,	0x0,	0x0,	0x0,	0xF9,	0x0,	0xC,	0x0
			db	0xE9,	0x0,	0x2B,	0x0,	0xDC,	0x0,	0x46,	0x0
			db	0xD4,	0x0,	0x56,	0x0,	0xCC,	0x0,	0x67,	0x0
			db	0xC4,	0x0,	0x77,	0x0,	0xBB,	0x0,	0x88,	0x0
			db	0xB3,	0x0,	0x98,	0x0,	0xAB,	0x0,	0xA9,	0x0
			db	0xA3,	0x0,	0xB9,	0x0,	0x9B,	0x0,	0xC9,	0x0
			db	0x92,	0x0,	0xDA,	0x0,	0x8A,	0x0,	0xEA,	0x0
			db	0x82,	0x0,	0xFB,	0x0,	0x0,	0xFF,	0xFF,	0x0
			db	0xFF,	0xFF,	0xFF,	0xFF,	0xFF,	0xFF,	0xFF,	0xFF
			db	0xFF,	0xFF,	0xFF,	0xFF,	0xFF,	0xFF,	0xFF,	0xFF
			db	0xFE,	0xEE,	0xEE,	0xEE,	0xEE,	0xEE,	0xEE,	0xEE
			db	0xEE,	0xEE,	0xEE,	0xEE,	0xEE,	0xEE,	0xEE,	0xEF
			db	0xFD,	0xDD,	0xDD,	0xDD,	0xDD,	0xDD,	0xDD,	0xDD
			db	0xDD,	0xDD,	0xDD,	0xDD,	0xDD,	0xDD,	0xDD,	0xDF
			db	0xFD,	0xDD,	0xDD,	0xDD,	0xDD,	0xDD,	0xDD,	0xDD
			db	0xDD,	0xDD,	0xDD,	0xDD,	0xDD,	0xDD,	0xDD,	0xDF
			db	0xFC,	0xCC,	0xCC,	0xCC,	0xCC,	0xCC,	0xCC,	0xCC
			db	0xCC,	0xCC,	0xCC,	0xCC,	0xCC,	0xCC,	0xCC,	0xCF
			db	0xFC,	0xCC,	0xCC,	0xCC,	0xCC,	0xCC,	0xCC,	0xCC
			db	0xCC,	0xCC,	0xCC,	0xCC,	0xCC,	0xCC,	0xCC,	0xCF
			db	0xFB,	0xBB,	0xBB,	0xBB,	0xBB,	0xBB,	0xBB,	0xBB
			db	0xBB,	0xBB,	0xBB,	0xBB,	0xBF,	0xFB,	0xBB,	0xBF
			db	0xFB,	0xBB,	0xBB,	0xBB,	0xBB,	0xBB,	0xBB,	0xBB
			db	0xBB,	0xBB,	0xBB,	0xBB,	0xBF,	0xFB,	0xBB,	0xBF
			db	0xFA,	0xAA,	0xAA,	0xAA,	0xAA,	0xAA,	0xAA,	0xAA
			db	0xAA,	0xAA,	0xAA,	0xAA,	0xAF,	0xFA,	0xAA,	0xAF
			db	0xFA,	0xAA,	0xAA,	0xAA,	0xAA,	0xAA,	0xAA,	0xAA
			db	0xAA,	0xAA,	0xAA,	0xAA,	0xAF,	0xFA,	0xAA,	0xAF
			db	0xF9,	0x99,	0x99,	0x99,	0x99,	0x99,	0x99,	0x99
			db	0x99,	0x99,	0x99,	0x99,	0x9F,	0xF9,	0x99,	0x9F
			db	0xF9,	0x99,	0x99,	0x99,	0x99,	0x99,	0x99,	0x99
			db	0x99,	0x99,	0x99,	0x99,	0x9F,	0xF9,	0x99,	0x9F
			db	0xF8,	0x88,	0x88,	0x88,	0xFF,	0x88,	0x88,	0x88
			db	0x88,	0xFF,	0x88,	0x88,	0x8F,	0xF8,	0x88,	0x8F
			db	0xF8,	0x88,	0x8F,	0xF8,	0xFF,	0x8F,	0xF8,	0x8F
			db	0xF8,	0xFF,	0x8F,	0xF8,	0x8F,	0xF8,	0x88,	0x8F
			db	0xF7,	0x77,	0x77,	0xFF,	0xFF,	0xFF,	0x77,	0x77
			db	0xFF,	0xFF,	0xFF,	0x77,	0x7F,	0xF7,	0x77,	0x7F
			db	0xF7,	0x77,	0x77,	0x7F,	0xFF,	0xF7,	0x77,	0x77
			db	0x7F,	0xFF,	0xF7,	0x77,	0x7F,	0xF7,	0x77,	0x7F
			db	0xF6,	0x66,	0x66,	0x6F,	0xFF,	0xF6,	0x66,	0x66
			db	0x6F,	0xFF,	0xF6,	0x66,	0x6F,	0xF6,	0x66,	0x6F
			db	0xF6,	0x66,	0x66,	0xFF,	0xFF,	0xFF,	0x66,	0x66
			db	0xFF,	0xFF,	0xFF,	0x66,	0x6F,	0xF6,	0x66,	0x6F
			db	0xF5,	0x55,	0x5F,	0xF5,	0xFF,	0x5F,	0xF5,	0x5F
			db	0xF5,	0xFF,	0x5F,	0xF5,	0x5F,	0xF5,	0x55,	0x5F
			db	0xF5,	0x55,	0x55,	0x55,	0xFF,	0x55,	0x55,	0x55
			db	0x55,	0xFF,	0x55,	0x55,	0x5F,	0xF5,	0x55,	0x5F
			db	0xF4,	0x44,	0x44,	0x44,	0x44,	0x44,	0x44,	0x44
			db	0x44,	0x44,	0x44,	0x44,	0x4F,	0xF4,	0x44,	0x4F
			db	0xF4,	0x44,	0x44,	0x44,	0x44,	0x44,	0x44,	0x44
			db	0x44,	0x44,	0x44,	0x44,	0x4F,	0xF4,	0x44,	0x4F
			db	0xF3,	0x33,	0x33,	0x33,	0x33,	0x33,	0x33,	0x33
			db	0x33,	0x33,	0x33,	0x33,	0x3F,	0xF3,	0x33,	0x3F
			db	0xF3,	0x33,	0x33,	0x33,	0x33,	0x33,	0x33,	0x33
			db	0x33,	0x33,	0x33,	0x33,	0x3F,	0xF3,	0x33,	0x3F
			db	0xF2,	0x22,	0x22,	0x22,	0x22,	0x22,	0x22,	0x22
			db	0x22,	0x22,	0x22,	0x22,	0x2F,	0xF2,	0x22,	0x2F
			db	0xF2,	0x22,	0x22,	0x22,	0x22,	0x22,	0x22,	0x22
			db	0x22,	0x22,	0x22,	0x22,	0x2F,	0xF2,	0x22,	0x2F
			db	0xF2,	0x22,	0x22,	0x22,	0x22,	0x22,	0x22,	0x22
			db	0x22,	0x22,	0x22,	0x22,	0x22,	0x22,	0x22,	0x2F
			db	0xF2,	0x22,	0x22,	0x22,	0x22,	0x22,	0x22,	0x22
			db	0x22,	0x22,	0x22,	0x22,	0x22,	0x22,	0x22,	0x2F
			db	0xF2,	0x22,	0x22,	0x22,	0x22,	0x22,	0x22,	0x22
			db	0x22,	0x22,	0x22,	0x22,	0x22,	0x22,	0x22,	0x2F
			db	0xF1,	0x11,	0x11,	0x11,	0x11,	0x11,	0x11,	0x11
			db	0x11,	0x11,	0x11,	0x11,	0x11,	0x11,	0x11,	0x1F
			db	0xF1,	0x11,	0x11,	0x11,	0x11,	0x11,	0x11,	0x11
			db	0x11,	0x11,	0x11,	0x11,	0x11,	0x11,	0x11,	0x1F
			db	0xFF,	0xFF,	0xFF,	0xFF,	0xFF,	0xFF,	0xFF,	0xFF
			db	0xFF,	0xFF,	0xFF,	0xFF,	0xFF,	0xFF,	0xFF,	0xFF
			db	0x0,	0x0,	0x0,	0x0,	0x0,	0x0,	0x0,	0x0
			db	0x0,	0x0,	0x0,	0x0,	0x0,	0x0,	0x0,	0x0
			db	0x0,	0x0,	0x0,	0x0,	0x0,	0x0,	0x0,	0x0
			db	0x0,	0x0,	0x0,	0x0,	0x0,	0x0,	0x0,	0x0
			db	0x0,	0x0,	0x0,	0x0,	0x0,	0x0,	0x0,	0x0
			db	0x0,	0x0,	0x0,	0x0,	0x0,	0x0,	0x0,	0x0
			db	0x0,	0x0,	0x0,	0x0,	0x0,	0x0,	0x0,	0x0
			db	0x0,	0x0,	0x0,	0x0,	0x0,	0x0,	0x0,	0x0
			db	0x0,	0x0,	0x0,	0x0,	0x0,	0x0,	0x0,	0x0
			db	0x0,	0x0,	0x0,	0x0,	0x0,	0x0,	0x0,	0x0
			db	0x0,	0x0,	0x0,	0x0,	0x0,	0x0,	0x0,	0x0
			db	0x0,	0x0,	0x0,	0x0,	0x0,	0x0,	0x0,	0x0
			db	0x0,	0x0,	0x0,	0x0,	0x0,	0x0,	0x0,	0x0
			db	0x0,	0x0,	0x0,	0x0,	0x0,	0x0,	0x0,	0x0
			db	0x0,	0x0,	0x0,	0x0,	0x0,	0x0,	0x0,	0x0
			db	0x0,	0x0,	0x0,	0x0,	0x0,	0x0,	0x0,	0x0
	align 4

	main_icon_grp_data	dd RVA main_icon_grp_header, 20, 0, 0

	main_icon_grp_header	dw 0, 1, 1
				dd 0x102020, 0x40001, 0x2E8
				dw main_icon_data.resid
	align 4

	; Data of the icon showed on the button used for copying generated password to the
	; clipboard.
	;
	copy_icon_data	dd RVA copy_idata, 0x2E8, 0, 0

	copy_idata	db	0x28,	0x0,	0x0,	0x0,	0x20,	0x0,	0x0,	0x0
			db	0x40,	0x0,	0x0,	0x0,	0x1,	0x0,	0x4,	0x0
			db	0x0,	0x0,	0x0,	0x0,	0x0,	0x0,	0x0,	0x0
			db	0x0,	0x0,	0x0,	0x0,	0x0,	0x0,	0x0,	0x0
			db	0x0,	0x0,	0x0,	0x0,	0x0,	0x0,	0x0,	0x0
			db	0x0,	0x0,	0x0,	0x0,	0x0,	0x0,	0x0,	0x0
			db	0x31,	0x2D,	0x2C,	0x0,	0x96,	0x60,	0x29,	0x0
			db	0xC4,	0x9F,	0x57,	0x0,	0x38,	0x3C,	0x8F,	0x0
			db	0x97,	0x6D,	0xA9,	0x0,	0x4A,	0x92,	0xAF,	0x0
			db	0xAB,	0xA4,	0x9B,	0x0,	0xDE,	0xB3,	0x97,	0x0
			db	0xB1,	0xCE,	0xAA,	0x0,	0xE8,	0xDC,	0xAE,	0x0
			db	0x99,	0xAA,	0xDB,	0x0,	0xA0,	0xD0,	0xF4,	0x0
			db	0xC0,	0xC0,	0xC0,	0x0,	0xFE,	0xFE,	0xFE,	0x0
			db	0x0,	0x0,	0x0,	0x0,	0x0,	0x0,	0x0,	0x0
			db	0x0,	0x0,	0x0,	0x0,	0x0,	0x0,	0x0,	0x0
			db	0x5,	0x55,	0x55,	0x55,	0x55,	0x55,	0x55,	0x55
			db	0x55,	0x55,	0x55,	0x55,	0x55,	0x55,	0x55,	0x50
			db	0x5,	0x55,	0x55,	0x55,	0x55,	0x55,	0x55,	0x55
			db	0x55,	0x55,	0x55,	0x55,	0x55,	0x55,	0x55,	0x50
			db	0x5,	0x55,	0x55,	0x55,	0x55,	0x55,	0x55,	0x55
			db	0x55,	0x55,	0x55,	0x55,	0x55,	0x55,	0x55,	0x50
			db	0x5,	0x55,	0x55,	0x55,	0x55,	0x55,	0x55,	0x55
			db	0x55,	0x55,	0x55,	0x55,	0x55,	0x55,	0x55,	0x50
			db	0x5,	0x55,	0x55,	0x55,	0x55,	0x50,	0x0,	0x0
			db	0x0,	0x0,	0x0,	0x0,	0x0,	0x5,	0x55,	0x50
			db	0x5,	0x55,	0x55,	0x55,	0x55,	0x58,	0xEE,	0xEE
			db	0xEE,	0xEE,	0xEE,	0xEE,	0xEE,	0x5,	0x55,	0x50
			db	0x5,	0x55,	0x55,	0x55,	0x55,	0x58,	0xFF,	0xFF
			db	0xFF,	0xFF,	0xFF,	0xFF,	0xFE,	0x5,	0x55,	0x50
			db	0x5,	0x55,	0x55,	0x55,	0x55,	0x58,	0xFF,	0xFF
			db	0xFF,	0xFF,	0xFF,	0xFF,	0xFE,	0x5,	0x55,	0x50
			db	0x5,	0x55,	0x55,	0x55,	0x55,	0x58,	0xFF,	0xFF
			db	0xFF,	0xFF,	0xFF,	0xFF,	0xFE,	0x5,	0x55,	0x50
			db	0x5,	0x55,	0x55,	0x0,	0x0,	0x8,	0xFF,	0xF5
			db	0x4C,	0x20,	0x97,	0xF,	0xFE,	0x5,	0x55,	0x50
			db	0x5,	0x55,	0x55,	0x8E,	0xEE,	0xE8,	0xFF,	0xF9
			db	0xFD,	0x8F,	0xFF,	0xFF,	0xFE,	0x5,	0x55,	0x50
			db	0x5,	0x55,	0x55,	0x8F,	0xFF,	0xF8,	0xFF,	0xF7
			db	0x0,	0xA,	0x53,	0xDF,	0xFE,	0x5,	0x55,	0x50
			db	0x5,	0x55,	0x55,	0x8F,	0xFF,	0xF8,	0xFF,	0xFF
			db	0xFF,	0xFF,	0xFF,	0xFF,	0xFE,	0x5,	0x55,	0x50
			db	0x5,	0x55,	0x55,	0x8F,	0xFF,	0xF8,	0xFF,	0xFF
			db	0xFF,	0xFF,	0xFF,	0xFF,	0xFE,	0x5,	0x55,	0x50
			db	0x5,	0x55,	0x55,	0x8F,	0xFF,	0x58,	0xFF,	0xF2
			db	0x2,	0x33,	0x70,	0xBF,	0xFE,	0x5,	0x55,	0x50
			db	0x5,	0x55,	0x55,	0x8F,	0xFF,	0x98,	0xFF,	0xFF
			db	0xFF,	0xFF,	0xFC,	0xBF,	0xFE,	0x5,	0x55,	0x50
			db	0x5,	0x55,	0x55,	0x8F,	0xFF,	0x78,	0xFF,	0xF3
			db	0x57,	0x22,	0x36,	0x5F,	0xFE,	0x5,	0x55,	0x50
			db	0x5,	0x55,	0x55,	0x8F,	0xFF,	0xF8,	0xFF,	0xFF
			db	0xFF,	0xFF,	0xFF,	0xF8,	0x0,	0x5,	0x55,	0x50
			db	0x5,	0x55,	0x55,	0x8F,	0xFF,	0xF8,	0xFF,	0xFF
			db	0xFF,	0xFF,	0xFF,	0xF8,	0xF8,	0x5,	0x55,	0x50
			db	0x5,	0x55,	0x55,	0x8F,	0xFF,	0x28,	0xFF,	0xFF
			db	0xFF,	0xFF,	0xFF,	0xF8,	0x80,	0x55,	0x55,	0x50
			db	0x5,	0x55,	0x55,	0x8F,	0xFF,	0xF8,	0x88,	0x88
			db	0x88,	0x88,	0x88,	0x88,	0x5,	0x55,	0x55,	0x50
			db	0x5,	0x55,	0x55,	0x8F,	0xFF,	0x35,	0x72,	0x23
			db	0x65,	0xFF,	0xE0,	0x55,	0x55,	0x55,	0x55,	0x50
			db	0x5,	0x55,	0x55,	0x8F,	0xFF,	0xFF,	0xFF,	0xFF
			db	0xFF,	0x80,	0x0,	0x55,	0x55,	0x55,	0x55,	0x50
			db	0x5,	0x55,	0x55,	0x8F,	0xFF,	0xFF,	0xFF,	0xFF
			db	0xFF,	0x8F,	0x80,	0x55,	0x55,	0x55,	0x55,	0x50
			db	0x5,	0x55,	0x55,	0x8F,	0xFF,	0xFF,	0xFF,	0xFF
			db	0xFF,	0x88,	0x5,	0x55,	0x55,	0x55,	0x55,	0x50
			db	0x5,	0x55,	0x55,	0x88,	0x88,	0x88,	0x88,	0x88
			db	0x88,	0x80,	0x55,	0x55,	0x55,	0x55,	0x55,	0x50
			db	0x5,	0x55,	0x55,	0x55,	0x55,	0x55,	0x55,	0x55
			db	0x55,	0x55,	0x55,	0x55,	0x55,	0x55,	0x55,	0x50
			db	0x5,	0x55,	0x55,	0x55,	0x55,	0x55,	0x55,	0x55
			db	0x55,	0x55,	0x55,	0x55,	0x55,	0x55,	0x55,	0x50
			db	0x5,	0x55,	0x55,	0x55,	0x55,	0x55,	0x55,	0x55
			db	0x55,	0x55,	0x55,	0x55,	0x55,	0x55,	0x55,	0x50
			db	0x5,	0x55,	0x55,	0x55,	0x55,	0x55,	0x55,	0x55
			db	0x55,	0x55,	0x55,	0x55,	0x55,	0x55,	0x55,	0x50
			db	0x0,	0x0,	0x0,	0x0,	0x0,	0x0,	0x0,	0x0
			db	0x0,	0x0,	0x0,	0x0,	0x0,	0x0,	0x0,	0x0
			db	0x0,	0x0,	0x0,	0x0,	0x0,	0x0,	0x0,	0x0
			db	0x0,	0x0,	0x0,	0x0,	0x0,	0x0,	0x0,	0x0
			db	0x0,	0x0,	0x0,	0x0,	0x0,	0x0,	0x0,	0x0
			db	0x0,	0x0,	0x0,	0x0,	0x0,	0x0,	0x0,	0x0
			db	0x0,	0x0,	0x0,	0x0,	0x0,	0x0,	0x0,	0x0
			db	0x0,	0x0,	0x0,	0x0,	0x0,	0x0,	0x0,	0x0
			db	0x0,	0x0,	0x0,	0x0,	0x0,	0x0,	0x0,	0x0
			db	0x0,	0x0,	0x0,	0x0,	0x0,	0x0,	0x0,	0x0
			db	0x0,	0x0,	0x0,	0x0,	0x0,	0x0,	0x0,	0x0
			db	0x0,	0x0,	0x0,	0x0,	0x0,	0x0,	0x0,	0x0
			db	0x0,	0x0,	0x0,	0x0,	0x0,	0x0,	0x0,	0x0
			db	0x0,	0x0,	0x0,	0x0,	0x0,	0x0,	0x0,	0x0
			db	0x0,	0x0,	0x0,	0x0,	0x0,	0x0,	0x0,	0x0
			db	0x0,	0x0,	0x0,	0x0,	0x0,	0x0,	0x0,	0x0
			db	0x0,	0x0,	0x0,	0x0,	0x0,	0x0,	0x0,	0x0
			db	0x0,	0x0,	0x0,	0x0,	0x0,	0x0,	0x0,	0x0
	align 4

	copy_icon_grp_data	dd RVA copy_icon_grp_header, 20, 0, 0

	copy_icon_grp_header	dw 0, 1, 1
				dd 0x102020, 0x40001, 0x2E8
				dw copy_icon_data.resid
	align 4

	; Data of the manifest embedded directly into the source file.
	;
	resdata	man
		db '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>'
		db '<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">'
		db '<assemblyIdentity '
			db 'version="', PROG_VERSION, '" '
			db 'processorArchitecture="X86" '
			db 'name="Mikołaj Hajduk.SimPaGen" '
			db 'type="win32"'
		db '/>'
		db '<description>Simple password generator.</description>'
		db '<dependency>'
			db '<dependentAssembly>'
				db '<assemblyIdentity '
					db 'type="win32" '
					db 'name="Microsoft.Windows.Common-Controls" '
					db 'version="6.0.0.0" '
					db 'processorArchitecture="X86" '
					db 'publicKeyToken="6595b64144ccf1df" '
					db 'language="*"'
				db '/>'
			db '</dependentAssembly>'
		db '</dependency>'
		db '</assembly>'
	endres
© 2007-2014, Mikołaj Hajduk