11<?xml version =" 1.0" encoding =" UTF-8" ?>
2- <Export generator =" Cache" version =" 25" zv =" Cache for Windows (x86-64) 2014.1.1 (Build 702U)" ts =" 2014-08-18 15:57:38 " >
2+ <Export generator =" Cache" version =" 25" zv =" Cache for Windows (x86-64) 2014.1.1 (Build 702U)" ts =" 2014-09-03 16:10:57 " >
33<CSP name =" CNARegistryExample.CSP" application =" /csp/dev/" default =" 1" ><![CDATA[
44<html>
55<head>
1111<body>
1212<form action="CNARegistryExample.csp" method="GET">
1313Subkey of HKEY_CURRENT_USER:<br>
14- <input type="text" name="subkey"><br>
14+ <input type="text" name="subkey" value="#($GET(%request.Data("param", 1)))#" ><br>
1515Parameter:<br>
16- <input type="text" name="param"><br>
16+ <input type="text" name="param" value="#($GET(%request.Data("subkey", 1)))#"><br>
17+ Path to libcna.dll:<br>
18+ <input type="text" name="path" value="#($GET(%request.Data("path", 1)))#"><br>
1719<button type="submit">Get key</button>
1820</form>
1921<script language="Cache" runat="server">
2022if ($Data(%request.Data("subkey", 1)) && $Data(%request.Data("param", 1))) {
2123 try {
24+
25+ // Получаем параметры HTTP-запроса
26+ set CNAPath = %request.Data("path", 1)
2227 set subkey = %request.Data("subkey", 1)
2328 set param = %request.Data("param", 1)
24- w subkey, "<br>"
25- w param, "<br>"
26-
27- set CNAPath = "C:\Users\dd\Dropbox\is\CNA\libcna.dll"
29+
30+ // Создаем объект класса CNA и загружаем туда стандартную бибилиотеку C
2831 set libc = ##class(CNA.CNA).%New(CNAPath)
2932 do libc.LoadLibrary("C:\Windows\System32\msvcrt.dll")
3033
34+ // Вызываем malloc, чтобы выделить память под буферы, кооторые используются в вызовах WinAPI
3135 set argTypes = $lb(libc.#SIZET)
3236 set phkey = libc.CallFunction("malloc", libc.#POINTER, argTypes, 4)
3337 set size = 1000
3438 set valueBuf = libc.CallFunction("malloc", libc.#POINTER, argTypes, size)
3539 set sizeBuf = libc.CallFunction("malloc", libc.#POINTER, argTypes, 4)
3640 do libc.PointerSetAt(sizeBuf, libc.#ULONG, 0, size)
3741
42+
43+ // Загружаем в CNA advapi - билиотеку, в которой находятся функции для работы с реестром
3844 set advapi = ##class(CNA.CNA).%New(CNAPath)
3945 do advapi.LoadLibrary("C:\Windows\System32\advapi32.dll")
4046
41- set argTypes = $lb(advapi.#LONG, advapi.#POINTER)
47+
48+ // Открываем ключ HKEY_CURRENT_USER
49+ // Прототип функции: LONG RegOpenCurrentUser(REGSAM samDesired, PHKEY phkResult);
50+ // LONG - алиас типа int, REGSAM - long, PHKEY - unsigned long *
51+ // В первом аргументе передаем права доступа, во втором - указатель на буфер, куда нужно записать дескриптор ключа
52+ // Константа 0x20019 означает, что мы открываем ключ с правами KEY_READ
4253
54+ set argTypes = $lb(advapi.#LONG, advapi.#POINTER)
4355 set res = advapi.CallFunction("RegOpenCurrentUser", advapi.#INT, argTypes, $zhex("20019"), phkey)
4456 if (res '= 0) {
4557 w "RegOpenCurrentUset error: " _ res _ "<br>"
4658 return
4759 }
4860
61+ // Получаем значание дескриптора ключа из буфера
4962 set hkey = advapi.PointerGetAt(phkey, advapi.#ULONG, 0)
5063
64+
5165 set argTypes = $lb(advapi.#ULONG, advapi.#POINTER, advapi.#POINTER, advapi.#ULONG, advapi.#POINTER, advapi.#POINTER, advapi.#POINTER)
5266 set pSubkey = advapi.ConvertStringToPointer(subkey)
5367 set pParam = advapi.ConvertStringToPointer(param)
@@ -56,7 +70,7 @@ if ($Data(%request.Data("subkey", 1)) && $Data(%request.Data("param", 1))) {
5670 if (res = 0) {
5771 w advapi.ConvertPointerToString(valueBuf), "<br>"
5872 } else {
59- w "RegGetValue Error: " _ res _ "<br >"
73+ w "<b><font color='red'> RegGetValue Error: " _ res _ "</font></b >"
6074 }
6175
6276 do advapi.FreeLibrary()
@@ -66,7 +80,9 @@ if ($Data(%request.Data("subkey", 1)) && $Data(%request.Data("param", 1))) {
6680 do libc.CallFunction("free", libc.#VOID, argTypes, sizeBuf)
6781 do libc.FreeLibrary()
6882 } catch ex {
83+ w "<b><font color='red'>"
6984 w $system.Status.GetErrorText(ex.AsStatus())
85+ w "</font></b>"
7086 }
7187}
7288</script>
0 commit comments