win32reg.erl

来自「OTP是开放电信平台的简称」· ERL 代码 · 共 349 行

ERL
349
字号
%% ``The contents of this file are subject to the Erlang Public License,%% Version 1.1, (the "License"); you may not use this file except in%% compliance with the License. You should have received a copy of the%% Erlang Public License along with this software. If not, it can be%% retrieved via the world wide web at http://www.erlang.org/.%% %% Software distributed under the License is distributed on an "AS IS"%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See%% the License for the specific language governing rights and limitations%% under the License.%% %% The Initial Developer of the Original Code is Ericsson Utvecklings AB.%% Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings%% AB. All Rights Reserved.''%% %%     $Id$%%-module(win32reg).-export([open/1, close/1,	 current_key/1, change_key/2, change_key_create/2,	 sub_keys/1, delete_key/1,	 value/2, values/1, set_value/3, delete_value/2,	 expand/1,	 format_error/1]).%% Key handles (always open).-define(hkey_classes_root, 16#80000000).-define(hkey_current_user, 16#80000001).-define(hkey_local_machine, 16#80000002).-define(hkey_users, 16#80000003).-define(hkey_performance_data, 16#80000004).-define(hkey_current_config, 16#80000005).-define(hkey_dyn_data, 16#80000006).%% Driver commands.-define(cmd_get_current, 0).-define(cmd_open_key, 1).-define(cmd_create_key, 2).-define(cmd_get_all_subkeys, 3).-define(cmd_get_value, 4).-define(cmd_get_all_values, 5).-define(cmd_set_value, 6).-define(cmd_delete_key, 7).-define(cmd_delete_value, 8).%% Data types.-define(reg_sc, 1).-define(reg_expand_sc, 2).-define(reg_binary, 3).-define(reg_dword, 4).%%% Exported functions.open(Modes) ->    case os:type() of	{win32, _} ->	    case open_mode(Modes, []) of		{error, Reason} ->		    {error, Reason};		ModeStr ->		    P = open_port({spawn, "registry__drv__ " ++ ModeStr}, []),		    {ok, {win32reg, P}}	    end;	_ ->	    {error, enotsup}    end.close({win32reg, Reg}) when is_port(Reg) ->    unlink(Reg),    exit(Reg, die),    ok.current_key({win32reg, Reg}) when is_port(Reg) ->    Cmd = [?cmd_get_current],    Reg ! {self(), {command, Cmd}},    {state, Hkey, Name} = get_result(Reg),    Root = hkey_to_string(Hkey),    {ok, case Name of	     [] -> Root;	     _  -> Root ++ [$\\|Name]	 end}.change_key({win32reg, Reg}, Key) when is_port(Reg) ->    change_key(Reg, ?cmd_open_key, Key).change_key_create({win32reg, Reg}, Key) when is_port(Reg) ->    change_key(Reg, ?cmd_create_key, Key).change_key(Reg, Cmd, Key) ->    case parse_key(Key, Reg) of	{ok, Hkey, Path} ->	    Reg ! {self(), {command, [Cmd, i32(Hkey), Path, 0]}},	    get_result(Reg);	{error, Reason} ->	    {error, Reason}    end.sub_keys({win32reg, Reg}) when is_port(Reg) ->    Cmd = [?cmd_get_all_subkeys],    Reg ! {self(), {command, Cmd}},    collect_keys(Reg, []).delete_key({win32reg, Reg}) when is_port(Reg) ->    Cmd = [?cmd_delete_key],    Reg ! {self(), {command, Cmd}},    get_result(Reg).    set_value({win32reg, Reg}, Name0, Value) when is_port(Reg) ->    Name =	case Name0 of	    default -> [];	    _ -> Name0	end,    {Type, V} = term_to_value(Value),    Cmd = [?cmd_set_value, Type, Name, 0, V],    Reg ! {self(), {command, Cmd}},    get_result(Reg).value({win32reg, Reg}, Name) when is_port(Reg) ->    Cmd = [?cmd_get_value, Name, 0],    Reg ! {self(), {command, Cmd}},    case get_result(Reg) of	{value, {Name, Value}} ->	    {ok, Value};	{error, Reason} ->	    {error, Reason}    end.    values({win32reg, Reg}) when is_port(Reg) ->    Cmd = [?cmd_get_all_values],    Reg ! {self(), {command, Cmd}},    collect_values(Reg, []).delete_value({win32reg, Reg}, Name0) when is_port(Reg) ->    Name =	case Name0 of	    default -> [];	    _ -> Name0	end,    Cmd = [?cmd_delete_value, Name, 0],    Reg ! {self(), {command, Cmd}},    get_result(Reg).expand(Value) ->    expand(Value, [], []).expand([$%, $%|Rest], [], Result) ->    expand(Rest, [], [$%|Result]);expand([$%, C|Rest], [], Result) ->    expand(Rest, [C], Result);expand([C|Rest], [], Result) ->    expand(Rest, [], [C|Result]);expand([$%|Rest], Env0, Result) ->    Env = lists:reverse(Env0),    case os:getenv(Env) of	false ->	    expand(Rest, [], Result);	Value ->	    expand(Rest, [], lists:reverse(Value)++Result)    end;expand([C|Rest], Env, Result) ->    expand(Rest, [C|Env], Result);expand([], [], Result) ->    lists:reverse(Result).format_error(ErrorId) ->    erl_posix_msg:message(ErrorId).					 %%% Implementation.collect_values(P, Result) ->    case get_result(P) of	ok ->	    {ok, lists:reverse(Result)};	{value, ValueData} ->	    collect_values(P, [ValueData|Result]);	{error, Reason} ->	    {error, Reason}    end.collect_keys(P, Result) ->    case get_result(P) of	ok ->	    {ok, lists:reverse(Result)};	{key, KeyData} ->	    collect_keys(P, [KeyData|Result]);	{error, Reason} ->	    {error, Reason}    end.    get_result(P) ->    receive	{P, {data, Data}} ->	    get_result1(Data)    end.get_result1([$e|Reason]) ->    {error, list_to_atom(Reason)};get_result1([$o]) ->    ok;get_result1([$k|Name]) ->    {key, Name};get_result1([$v|Rest0]) ->    {ok, Type, Rest1} = i32_on_head(Rest0),    {ok, Name0, Value} = get_cstring(Rest1),    Name = 	case Name0 of	    [] -> default;	    _ ->  Name0	end,    {value, {Name, encode_value(Type, Value)}};get_result1([$s|Rest0]) ->    {ok, Hkey, Name} = i32_on_head(Rest0),    {state, Hkey, Name}.encode_value(?reg_sc, Value) ->    Value;encode_value(?reg_expand_sc, Value) ->    Value;encode_value(?reg_dword, Value) ->    i32(Value);encode_value(_, Value) ->    list_to_binary(Value).term_to_value(Int) when is_integer(Int) ->    {i32(?reg_dword), i32(Int)};term_to_value(String) when is_list(String) ->    {i32(?reg_sc), [String, 0]};term_to_value(Bin) when is_binary(Bin) ->    {i32(?reg_binary), Bin};term_to_value(_) ->    exit(badarg).    get_cstring(List) ->    get_cstring(List, []).get_cstring([0|Rest], Result) ->    {ok, lists:reverse(Result), Rest};get_cstring([C|Rest], Result) ->    get_cstring(Rest, [C|Result]);get_cstring([], Result) ->    {ok, lists:reverse(Result), []}.	    i32(Int) when is_integer(Int) ->    [(Int bsr 24) band 255,     (Int bsr 16) band 255,     (Int bsr  8) band 255,     Int band 255];i32([X1, X2, X3, X4]) ->    (X1 bsl 24) bor (X2 bsl 16) bor (X3 bsl 8) bor X4.i32_on_head([X1, X2, X3, X4 | Rest]) ->    {ok, (X1 bsl 24) bor (X2 bsl 16) bor (X3 bsl 8) bor X4, Rest}.parse_key([$\\|Rest], _) ->    parse_root(Rest, []);parse_key(Key, Reg) ->    parse_relative(Key, Reg).parse_relative(Path, Reg) ->    Cmd = [?cmd_get_current],    Reg ! {self(), {command, Cmd}},    {state, RootHandle, Name} = get_result(Reg),    Original = split_key(Name),    Relative = lists:reverse(split_key(Path)),    case parse_relative1(Relative, Original) of	NewPath ->	    {ok, RootHandle, NewPath}    %% XXX Error handling.    end.parse_relative1([".."|T1], [_|T2]) ->    parse_relative1(T1, T2);parse_relative1([Comp|Rest], Result) ->    parse_relative1(Rest, [Comp|Result]);parse_relative1([], Result) ->    reverse_and_join(Result, []).reverse_and_join([X|Rest], []) ->    reverse_and_join(Rest, [X]);reverse_and_join([X|Rest], Result) ->    reverse_and_join(Rest, [X, "\\" | Result]);reverse_and_join([], Result) ->    Result.split_key(Key) ->    split_key(Key, [], []).split_key([$\\|Rest], Current, Result) ->    split_key(Rest, [], [lists:reverse(Current)|Result]);split_key([C|Rest], Current, Result) ->    split_key(Rest, [C|Current], Result);split_key([], [], Result) ->    Result;split_key([], Current, Result) ->    [lists:reverse(Current)|Result].parse_root([$\\|Rest], Result) ->    Root = 	case lists:reverse(Result) of	    [$h, $k, $e, $y, $_|Root0] ->		Root0;	    Root0 ->		Root0	end,    case root_to_handle(list_to_atom(Root)) of	false ->	    {error, enoent};	Handle ->	    {ok, Handle, Rest}    end;parse_root([C|Rest], Result) ->    parse_root(Rest, [C|Result]);parse_root([], Result) ->    parse_root([$\\], Result).root_to_handle(classes_root) -> ?hkey_classes_root;root_to_handle(hkcr) -> ?hkey_classes_root;root_to_handle(current_user) -> ?hkey_current_user;root_to_handle(hkcu) -> ?hkey_current_user;root_to_handle(local_machine) -> ?hkey_local_machine;root_to_handle(hklm) -> ?hkey_local_machine;root_to_handle(users) -> ?hkey_users;root_to_handle(hku) -> ?hkey_users;root_to_handle(current_config) -> ?hkey_current_config;root_to_handle(hkcc) -> ?hkey_current_config;root_to_handle(dyn_data) -> ?hkey_dyn_data;root_to_handle(hkdd) -> ?hkey_dyn_data;root_to_handle(performance_data) -> ?hkey_performance_data;root_to_handle(_) -> false.hkey_to_string(?hkey_classes_root) -> "\\hkey_classes_root";hkey_to_string(?hkey_current_user) -> "\\hkey_current_user";hkey_to_string(?hkey_local_machine) -> "\\hkey_local_machine";hkey_to_string(?hkey_users) -> "\\hkey_users";hkey_to_string(?hkey_performance_data) -> "\\hkey_performance_data";hkey_to_string(?hkey_current_config) -> "\\hkey_current_config";hkey_to_string(?hkey_dyn_data) -> "\\hkey_dyn_data".open_mode([read|Rest], Result) ->    open_mode(Rest, [$r|Result]);open_mode([write|Rest], Result) ->    open_mode(Rest, [$w|Result]);open_mode([], Result) ->    Result;open_mode(_, _) ->    {error, einval}.

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?