Загрузка
Английский
Польский
Домашняя страница Николая Гайдука

Простой генератор паролей

П
рограмма SimPaGen это несложное в использовании, небольшое и очень удобное приложение для создания паролей. Написанная на ФАСМе утилита облегчает процесс создания надёжных паролей используемых для доступа к форумам, почтовым ящикам и другим сайтам.

Вот короткая демонстрация приложения в работе:

Технические детали

Создающиеся пароли состоят из символов любой комбинации четырёх основных категорий:

  • буквы A, ..., Z,
  • буквы a, ..., z,
  • цифры 0, ..., 9,
  • символ подчёркивания '_'
и других выбранных пользователем символов. Количество всех возможных непустых наборов знаков равно 2224-1 (количество всех непустых подмножеств набора символов с шестнадцатеричными кодами от 0x20 до 0xFF). Максимальная длина созданного пароля равна 9999 символам. Созданный пароль можно скопировать в буфер обмена пользуясь кнопкой

Кроме того, нажатие сочетания клавиш WIN + F12 даёт возможность создания нового пароля и немедленного помещения его в буфере обмена, даже когда окно приложения неактивно. Настройки программы определяющее длину пароля и набор составных символов создающихся паролей хранятся перед концом работы приложения в следующем подразделе системного реестра:

HKEY_CURRENT_USER\Software\SimPaGen\<версия_программы>

В приложении использованы функции CryptoAPI библиотеки 'advapi32.dll', благодаря чему созданная последовательность символов пароля является "криптографически случайной".

Исходный файл содержит встроенные непосредственно данные иконок и манифеста.

Программа является примером использования метода сабклассинга полей редактирования.

История проекта

v.2008.08.12.0 - первая публично доступна версия программы.

v.2008.09.11.0 - добавления и изменения:

  • добавлена кнопка, которая копирует пароль из поля редактирования программы в буфер обмена,
  • добавлено сочетание клавиш WIN + F12, которое применяется для создания нового пароля и помещения его в буфере обмена (сочетание работает тоже если окно приложения неактивно),
  • добавлена возможность записывания текущих настроек программы (длина пароля и набор составных символов создающихся паролей) в системном реестре,
  • упрощены и исправлены операции касающиеся таблицы определяющей характеристическую функцию набора знаков создающихся паролей.

Исходник

Ниже представлен исходник программы:

; Программа на ФАСМе для создания паролей состоящих из символов любой комбинации
; четырёх основных категорий:
;	
;	* буквы A, ..., Z,
;	* буквы a, ..., z,
;	* цифры 0, ..., 9,
;	* символ подчёркивания '_'
;
; и других выбранных пользователем символов. Количество всех возможных непустых
; наборов знаков равно 2^224-1 (количество всех непустых подмножеств набора символов
; с шестнадцатеричными кодами от 0x20 до 0xFF). Максимальная длина созданного пароля
; равна 9999 символам. Созданный пароль можно скопировать в буфер обмена пользуясь
; кнопкой с иконкой.
;
; Кроме того, нажатие сочетания клавиш WIN + F12 даёт возможность создания нового
; пароля и немедленного помещения его в буфере обмена, даже когда окно приложения
; неактивно.
;
; Настройки программы определяющее длину пароля и набор составных символов создающихся
; паролей хранятся перед концом работы приложения в следующем подразделе системного
; реестра:
;
;		HKEY_CURRENT_USER\Software\SimPaGen\<версия_программы>
;
; В приложении использованы функции CryptoAPI библиотеки 'advapi32.dll', благодаря
; чему созданная последовательность символов пароля является "криптографически
; случайной".
;
; Исходный файл содержит встроенные непосредственно данные иконок и манифеста.
;
; Программа является примером использования метода сабклассинга полей редактирования.
;
; (C) Mikołaj Hajduk, 11.09.2008.
;
; Домашняя страница:	http://mikhajduk.houa.org
; E-mail:		mikhajduk@gmail.com
;
format PE GUI 4.0

; Включение файла, который содержит все нужные макросы ФАСМа использованы в программе.
;
include 'win32wx.inc'

; Определение кодировки, в которой записан исходный файл.
;
include '\ENCODING\utf8.inc'

; Определение константы, которая содержит информацию о версии программы.
;
PROG_VERSION	equ '2008.09.11.0'


; Дефиниции глобальных данных.
;
section '.data' data readable writeable

	; Строки, которые содержат имена встроенных классов системы Windows.
	;
	_edit		du 'EDIT', 0
	_button		du 'BUTTON', 0
	_static		du 'STATIC', 0

	; Строки, которые содержат имена определённых нами классов.
	;
	_MainClass	du 'SimPaGen', 0
	_PassPanelClass	du 'PassPanel', 0
	_CharPanelClass	du 'CharPanel', 0

	; Дефиниции новых классов используемых в программе.
	;
	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

	; Хэндл шрифта используемого для описания контролов программы.
	;
	Font		dd ?

	; Структура, которая содержит информации об обрабатываемом сообщении.
	;
	msg		MSG

	; Хэндл модуля приложения.
	;
	hInstance	dd ?

	; Хэндл панели, в которой создаются пароли.
	;
	PassPanel	dd ?

	; Хэндл панели, в которой определяем набор символов для генерированных
	; паролей.
	;
	CharPanel	dd ?

	; Таблица определяющая характеристическую функцию множества составных символов.
	;
	CharFun		rd 7

	; Таблица, которая содержит строковое представление длины создающихся паролей.
	;
	PassLen		du '10'
			rb 6

	; Переменная, которая содержит состав флагов соответствующих состоянии
	; переключателей определяющих факт использования основных категорий
	; символов.
	;
	Flags		dw 0


; Исполняемый код программы.
;
section '.code' code readable writeable executable

	start:
		; Проверка загрузки библиотеки 'comctl32.dll'. Это необходимо для работы с манифестом.
		;
		invoke	InitCommonControls

		; Получение хэндла модуля приложения.
		;
		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

		; Регистрация используемых в программе классов окон.
		;
		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

	; Петля обработки сообщений.
	;
	msg_loop:
		invoke	GetMessage, msg, NULL, 0, 0
		cmp	eax, -1
		je	error

		cmp	eax, 1
		jb	end_loop
		jne	msg_loop

		; Если данное сообщение касается любой панели, тогда обрабатываем его
		; для перехвата нажатий клавиши TAB и клавиш управляющих курсором
		; (выбор данного контрола панели).
		;
		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]


; Процедура управления окном приложения.
;
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:
		; Создание шрифта используемого в полях редактирования, метках и кнопках.
		;
		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

		; Создание подраздела системного реестра (или его открытие, если уже существовал)
		; связанного с приложением.
		;
		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

		; Проверка значения переменной 'Disposition' возвращенного функцией 'RegCreateKeyEx'.
		;
		cmp	dword [ebx], REG_CREATED_NEW_KEY
		jne	.CreatePanels

		; Если значение это подтверждает факт создания нового подраздела системного реестра,
		; тогда в реестр записываются стандартные значения определяющее длину паролей
		; и характеристическую функцию набора составных символов.
		;
		.SaveStartRegValues:
			; Выделение блока памяти для хранения значений подраздела системного
			; реестра связанного с приложением.
			;
			invoke	LocalAlloc, LMEM_ZEROINIT, 29
			test	eax, eax
			jz	.failed
			xchg	ebx, eax

			; Запись состояния переключателей определяющих использование основных
			; категорий символов (по умолчанию используются буквы A-Z и цифры 0-9).
			;
			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

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

			; Освобождение блока памяти использованного как буфер для значений
			; подраздела системного реестра.
			;
			invoke	LocalFree, ebx
			test	eax, eax
			jnz	.failed

			; Запись в реестре строкового представления стандартной длины пароля.
			;
			invoke	RegSetValueEx, [.hKey], .PassLenRegVal, 0, REG_SZ, PassLen, 10
			test	eax, eax
			jnz	.failed

		.CreatePanels:

			; Создание панели, в которой создаются пароли.
			;
			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

			; Создание панели, в которой определяем набор символов для генерируемых паролей.
			;
			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

			; Загрузка характеристической функции набора знаков записанной в связанном
			; с приложением подразделе системного реестра.
			;
			invoke	RegQueryValueEx, [.hKey], .CharFunRegVal, 0, 0, CharFun, .CharFunBufSize
			test	eax, eax
			jnz	.failed

			; Загрузка строкового представления длины создающихся паролей.
			;
			invoke	RegQueryValueEx, [.hKey], .PassLenRegVal, 0, 0, PassLen, .PassLenBufSize
			test	eax, eax
			jnz	.failed

			; Помещение этого представления в поле редактирования 'ID_PASSLEN'.
			;
			invoke	SendDlgItemMessage, [PassPanel], ID_PASSLEN, WM_SETTEXT, 0, PassLen

			; Выделение блока памяти, в котором хранятся определённый пользователем набор
			; составных символов.
			;
			invoke	LocalAlloc, LMEM_ZEROINIT, 450
			test	eax, eax
			jz	.failed
			xchg	edi, eax
			mov	esi, edi

			; Цикл, в котором характеристическая функция превращается в строку символов Unicode,
			; содержащую определённый пользователем набор символов.
			;
			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

			; Помещение этой строки в поле редактирования 'ID_PASSCHARS'.
			;
			invoke	SendDlgItemMessage, [CharPanel], ID_PASSCHARS, WM_SETTEXT, 0, esi

			; Загрузка набора флагов определяющих состояние переключателей соответствующих
			; основным категориям символов.
			;
			invoke	RegQueryValueEx, [.hKey], .FlagsRegVal, 0, 0, esi, .FlagsBufSize
			test	eax, eax
			jnz	.failed

			movzx	ebx, word [esi]

			; В зависимости от значения флагов определяем состояние данных переключателей.
			;
			.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:
				; Освобождение блока памяти использованного для хранения определённого
				; пользователем набора составных символов.
				;
				invoke	LocalFree, esi
				test	eax, eax
				jnz	.failed

		; Эмуляция нажатия кнопки 'Создай' для создания примерного пароля.
		;
		invoke	SendDlgItemMessage, [PassPanel], ID_GENBTN, BM_CLICK, 0, 0

		xor	eax, eax
		jmp	.finish

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

	.wmdestroy:
		;
		; Запись настроек программы в соответствующем подразделе системного реестра.
		;

		; Загрузка в таблицу 'CharFun' характеристической функции составного набора
		; символов.
		;
		invoke	SendMessage, [CharPanel], WM_GETCHARSET, 0, 0

		; В зависимости от значения флагов из характеристической функции исключаем
		; соответствующее основные категории символов.
		;
		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

		; Запись в подразделе системного реестра строкового представления длины
		; создающихся паролей, модифицированной характеристической функции набора
		; символов и набора флагов.
		;
		.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

		; Закрытие подраздела системного реестра связанного с приложением.
		;
		invoke	RegCloseKey, [.hKey]
		test	eax, eax
		jnz	.failed

		; Удаление ненужного шрифта.
		;
		invoke	DeleteObject, [Font]
		test	eax, eax
		jz	.failed

		invoke	PostQuitMessage, 0
		xor	eax, eax

	.finish:
		pop	edi esi ebx

		ret

	align 4

	; Переменные, используемые для операций на подразделе системного реестра.
	;
	.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


; Процедура управления парольной панелью.
;
proc	PassPanelProc, hwnd, wmsg, wparam, lparam

	locals	
		Password	dd ?
		PassLen		dd ?
		CharTabLen	dd ?
	endl

	; Тип провайдера криптографических услуг (CSP) используемого
	; для создания случайной последовательности символов пароля.
	;
	PROV_RSA_FULL	= 1

	; Дефиниции констант соответствующих идентификаторам контролов панели.
	;
	ID_GENBTN	= 101
	ID_CLIPBTN	= 102

	ID_PASSEDIT	= 201
	ID_PASSLEN	= 202

	; Идентификатор сочетания клавиш WIN + F12.
	;
	ID_HOTKEY	= 1

	; Дефиниция констант соответствующих номерам сообщений используемых для
	; управления полями редактирования.
	;
	; Константы равны WM_USER + 2 для избежания возможных конфликтов
	; с сообщениями DM_GETDEFID и DM_SETDEFID, равными номерам WM_USER и
	; WM_USER + 1, которые может вызвать функция 'IsDialogMessage'.
	;
	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:
		; Определение провайдера криптографических услуг, хэндл которого помещаем
		; в переменную '.hProv'.
		;
		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, "Пароль"
		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, "Длина:"
		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

		; Замена стандартной процедуры обслуживания поля редактирования 'ID_PASSLEN'
		; новой, определённой нами.
		;
		invoke	SetWindowLong, ebx, GWL_WNDPROC, PassLenEditProc
		test	eax, eax
		jz	.failed
		mov	[PassLenEditProc.OldWndProc], eax

		; Определение максимального количества символов, которые можно ввести в поле
		; длины паролей.
		;
		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

		; Загрузка иконки с изображением карточек, которая будет помещена на кнопке
		; используемой для копирования созданного пароля в буфер обмена.
		;
		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, "Создай"
		test	eax, eax
		jz	.failed

		; Выделение блока памяти для таблицы составных символов генерируемых паролей.
		;
		invoke	LocalAlloc, LMEM_ZEROINIT, 224
		test	eax, eax
		jz	.failed
		mov	[.CharTab], eax

		; Регистрация сочетания клавиш WIN + F12 связанного с окном приложения.
		;
		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

	; Операции исполняемые после нажатия кнопки 'Создай'.
	;
	.GenBtn:

		; Посылка полю редактирования 'ID_PASSLEN' пользовательского сообщения для
		; определения длины генерируемых паролей.
		;
		invoke	SendDlgItemMessage, [hwnd], ID_PASSLEN, WM_GETPASSLEN, 0, 0
		test	eax, eax
		jz	.clear
		mov	[PassLen], eax

		; Посылка "символьной" панели пользовательского сообщения для определения выбранного
		; набора символов.
		;
		invoke	SendMessage, [CharPanel], WM_GETCHARSET, 0, 0

		; Цикл, в котором преображаем характеристическую функцию набора символов в таблицу
		; составных знаков генерированных паролей.
		;
		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

		; Определение длины таблицы символов.
		;
		sub	edi, [.CharTab]

		test	edi, edi
		jz	.clear

		mov	[CharTabLen], edi

		; Превращение длины пароля в символах в количество байтов необходимых для
		; хранения созданного пароля.
		;
		mov	ebx, [PassLen]
		shl	ebx, 1
		mov	eax, ebx
		add	eax, 2

		; Выделение блока памяти для созданного пароля.
		;
		invoke	LocalAlloc, LMEM_ZEROINIT, eax
		test	eax, eax
		jz	.failed

		mov	[Password], eax

		; Заполнение буфера случайным содержимым.
		;
		invoke	CryptGenRandom, [.hProv], ebx, eax
		test	eax, eax
		jz	.failed

		; Цикл, в котором байты созданного пароля заменяем символами принадлежащими
		; множеству допускаемых символов.
		;
		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

		; Помещение созданного пароля в поле редактирования 'ID_PASSEDIT'.
		;
		invoke	SendDlgItemMessage, [hwnd], ID_PASSEDIT, WM_SETTEXT, 0, [Password]

		; Освобождение блока памяти выделенного для хранения пароля.
		;
		invoke	LocalFree, [Password]
		test	eax, eax
		jnz	.failed

		jmp	.finish

	; Операции исполняемые после нажатия сочетания клавиш WIN + F12.
	;
	.wmhotkey:
		cmp	[wparam], ID_HOTKEY
		jne	.finish

		; Создание нового пароля.
		;
		invoke	SendDlgItemMessage, [hwnd], ID_GENBTN, BM_CLICK, 0, 0

	; Загрузка пароля в буфер обмена после нажатия кнопки с иконкой или использования
	; сочетания клавиш WIN + F12.
	;
	.copy:
		; Определение количества символов пароля и вычисление количества байтов
		; буфера предназначенного для загрузки скопированного пароля. 
		;
		invoke	SendDlgItemMessage, [hwnd], ID_PASSEDIT, WM_GETTEXTLENGTH, 0, 0
		inc	eax
		mov	ebx, eax
		shl	eax, 1

		; Выделение блока памяти для копированного пароля.
		;
		invoke	GlobalAlloc, GHND + GMEM_DDESHARE, eax		; GHND = GMEM_MOVEABLE + GMEM_ZEROINIT
		test	eax, eax
		jz	.failed

		; Блокировка блока памяти и получение указателя на его первый байт.
		;
		invoke	GlobalLock, eax
		test	eax, eax
		jz	.failed
		xchg	esi, eax

		; Открытие буфера обмена и блокировка возможности изменения его
		; содержимого другими приложениями.
		;
		invoke	OpenClipboard, [hwnd]
		test	eax, eax
		jz	.failed

		; Очистка буфера обмена, освобождение всех хэндлов данных находящихся
		; внутри и привязка его к окну приложения.
		;
		invoke	EmptyClipboard
		test	eax, eax
		jz	.failed

		; Загрузка пароля в выделенный блок памяти.
		;
		invoke	SendDlgItemMessage, [hwnd], ID_PASSEDIT, WM_GETTEXT, ebx, esi

		; Перенос пароля (в формате Unicode) в буфер обмена.
		;
		invoke	SetClipboardData, CF_UNICODETEXT, esi
		test	eax, eax
		jz	.failed

		; Снятие блокировки с блока памяти используемого как буфер для загрузки
		; паролей.
		;
		invoke	GlobalUnlock, esi
		test	eax, eax
		jz	.failed

		; Закрытие буфера обмена, что даёт возможность доступа к нему другим
		; приложениям.
		;
		invoke	CloseClipboard
		test	eax, eax
		jz	.failed

		jmp	.finish

	; Очищение поля 'ID_PASSEDIT' в случае пустого множества составных символов или для длины
	; пароля равной нулю.
	;
	.clear:
		invoke	SendDlgItemMessage, [hwnd], ID_PASSEDIT, WM_SETTEXT, 0, 0
		jmp	.finish

	.wmdestroy:
		; Освобождение сочетания клавиш WIN + F12.
		;
		invoke	UnregisterHotKey, [hwnd], ID_HOTKEY
		test	eax, eax
		jz	.failed

		; Освобождение блока памяти выделенного для таблицы составных знаков.
		;
		invoke	LocalFree, [.CharTab]
		test	eax, eax
		jnz	.failed

		; Освобождение хэндла провайдера криптографических услуг.
		;
		invoke	CryptReleaseContext, [.hProv], 0
		test	eax, eax
		jz	.failed

		xor	eax, eax

	.finish:
		pop	edi esi edx ecx ebx
		ret

	align 4

	; Хэндл таблицы составных знаков.
	;
	.CharTab	dd ?

	; Хэндл провайдера криптографических услуг.
	;
	.hProv		dd ?
endp


; Новая процедура обслуживания поля редактирования предназначенного для определения длины
; пароля.
;
proc	PassLenEditProc, hwnd, wmsg, wparam, lparam

	cmp	[wmsg], WM_CHAR
	je	.wmchar
	cmp	[wmsg], WM_GETPASSLEN
	je	.wmuser
	cmp	[wmsg], WM_PASTE	; Блокировка операции вставки текста
	je	.finish			; в поле редактирования.

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

	; Поле редактирования принимает только символы '0', ..., '9' и 'backspace'.
	;
	.wmchar:
		mov	eax, [wparam]

		cmp	eax, VK_BACK
		je	.defwndproc

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

		jmp	.defwndproc

	; После получения сообщения WM_GETPASSLEN поле редактирования рассчитывает
	; число соответствующее последовательности десятичных цифр и помещает это
	; значение в регистре eax. Благодаря этому число доступно в процедуре, которая
	; отправила сообщение.
	;
	.wmuser:
		push	ebx esi

		; Получение содержимого поля редактирования.
		;
		lea	esi, [PassLen]
		invoke	SendMessage, [hwnd], WM_GETTEXT, 5, esi

		; Цикл, в котором рассчитываем значение соответствующее последовательности
		; десятичных цифр.
		;
		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

	; Хэндл оригинальной процедуры обслуживания поля редактирования.
	;
	.OldWndProc	dd ?
endp


; Процедура обслуживания панели, в которой определяем набор составных символов для
; создающихся паролей.
;
proc	CharPanelProc, hwnd, wmsg, wparam, lparam

	; Дефиниции констант соответствующих идентификаторам контролов панели.
	;
	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, "Применяемые символы"
		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, "Другие:"
		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

		; Замена стандартной процедуры обслуживания поля редактирования 'ID_PASSCHARS'
		; новой, определённой нами.
		;
		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

	; Если данное сообщение касается любого переключателя, тогда изменяем значение
	; соответствующего флага.
	;
	.wmcommand:
		mov	eax, [wparam]
		and	eax, 0FFFFh
		jz	.defwndproc

		cmp	eax, ID_CHKBOX4
		ja	.defwndproc

		dec	eax
		btc	[Flags], ax

		jmp	.defwndproc

	; В случае перехвата сообщения WM_GETCHARSET передаем его полю редактирования
	; 'ID_PASSCHARS', которое изменит характеристическую функцию учитывая определённый
	; пользователем набор символов.
	;
	.wmuser:
		invoke	SendDlgItemMessage, [hwnd], ID_PASSCHARS, WM_GETCHARSET, 0, 0
		jmp	.finish

	.wmdestroy:
		xor	eax, eax

	.finish:
		pop	ebx
		ret

endp


; Новая процедура обслуживания поля редактирования, в котором пользователь определяет
; собственный набор символов для генерируемых паролей.
;
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	; Блокировка операции вставки текста
	je	.finish			; в поле редактирования.

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

	; Ограничение набора знаков, которые можно ввести пользуясь клавиатурой,
	; до символов соответствующих шестнадцатеричным кодам от 20h до FFh и
	; символа 'backspace'.
	;
	.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

	; В случае перехвата сообщения WM_GETCHARSET содержимое поля
	; редактирования перерабатывается для дополнения символами
	; определёнными пользователем характеристической функции набора
	; знаков создающихся паролей.
	;
	.wmuser:
		push	ebx ecx esi edi

		; Очистка таблицы определяющей характеристическую функцию набора
		; составных символов создающихся паролей.
		;
		xor	eax, eax
		mov	ecx, 7
		mov	edi, CharFun
		cld
		rep	stosd

		; Загрузка в регистр ebx информации о состоянии переключателей.
		;
		movzx	ebx, [Flags]

		; Если любой из флагов соответствующих переключателям установлен,
		; тогда характеристическую функцию дополняем нужной основной 
		; категорией символов.
		;
		.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

		; Дополнение характеристической функции символами определёнными
		; пользователем.
		;
		.OtherChars:
			; Определение длины содержимого поля редактирования.
			;
			invoke	SendMessage, [hwnd], WM_GETTEXTLENGTH, 0, 0
			inc	eax
			mov	ebx, eax
			shl	eax, 1

			; Выделение блока памяти предназначенного для текста полученного
			; из поля редактирования.
			;
			invoke	LocalAlloc, LMEM_ZEROINIT, eax
			test	eax, eax
			jz	.failed

			mov	[Buffer], eax

			; Помещение содержимого поля редактирования в выделенном буфере.
			;
			invoke	SendMessage, [hwnd], WM_GETTEXT, ebx, eax

			; Цикл, в котором устанавливаем биты характеристической функции набора
			; символов соответствующее кодам знаков определённых пользователем.
			;
			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:
				; Освобождение блока памяти выделенного для буфера.
				;
				invoke	LocalFree, [Buffer]
				test	eax, eax
				jnz	.failed

		pop	edi esi ecx ebx

	.finish:
		ret

	align 4

	; Хэндл оригинальной процедуры обслуживания поля редактирования.
	;
	.OldWndProc	dd ?
endp


; Процедура обслуживания "непредвиденных случаев", показывающая окно с сообщением
; об ошибке, которая случилась во время работы программы.
;
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 '.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', 'Простой генератор паролей.',\
			'LegalCopyright', '(C) Mikołaj Hajduk, 2008',\
			'FileVersion', PROG_VERSION,\
			'ProductVersion', PROG_VERSION,\
			'OriginalFilename', 'SimPaGen.exe'

	; Данные главной иконки программы включенной непосредственно в исходник.
	;
	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

	; Данные иконки помещенной на кнопке используемой для копирования созданного пароля
	; в буфер обмена.
	;
	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

	; Данные манифеста включенного непосредственно в исходник.
	;
	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>Простой генератор паролей.</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