registry.c
上传用户:kjfoods
上传日期:2020-07-06
资源大小:29949k
文件大小:12k
源码类别:

midi

开发平台:

Unix_Linux

  1. /*
  2.  * $Id: 5bc802ff84d51169df6508f41d2df50d7efef27f $
  3.  *
  4.  * Copyright (C) 1999 Alexandre Julliard
  5.  *
  6.  * Originally distributed under LPGL 2.1 (or later) by the Wine project.
  7.  *
  8.  * Modified for use with MPlayer, detailed CVS changelog at
  9.  * http://www.mplayerhq.hu/cgi-bin/cvsweb.cgi/main/
  10.  *
  11.  * File now distributed as part of VLC media player with no modifications.
  12.  *
  13.  * This program is free software; you can redistribute it and/or modify
  14.  * it under the terms of the GNU General Public License as published by
  15.  * the Free Software Foundation; either version 2 of the License, or
  16.  * (at your option) any later version.
  17.  *
  18.  * This program is distributed in the hope that it will be useful,
  19.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  20.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  21.  * GNU General Public License for more details.
  22.  *
  23.  * You should have received a copy of the GNU General Public License
  24.  * along with this program; if not, write to the Free Software
  25.  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
  26.  */
  27. #include "config.h"
  28. #include <stdio.h>
  29. #include <stdlib.h>
  30. #include <fcntl.h>
  31. #include <unistd.h>
  32. #include <pwd.h>
  33. #include <sys/types.h>
  34. #include "wine/winbase.h"
  35. #include "wine/winreg.h"
  36. #include "wine/winnt.h"
  37. #include "wine/winerror.h"
  38. #include "ext.h"
  39. #include "registry.h"
  40. //#undef TRACE
  41. //#define TRACE printf
  42. extern char *get_path ( char * );
  43. // ...can be set before init_registry() call
  44. char* regpathname = NULL;
  45. static char* localregpathname = NULL;
  46. typedef struct reg_handle_s
  47. {
  48. int handle;
  49. char* name;
  50. struct reg_handle_s* next;
  51. struct reg_handle_s* prev;
  52. } reg_handle_t;
  53. struct reg_value
  54. {
  55. int type;
  56. char* name;
  57. int len;
  58. char* value;
  59. };
  60. static struct reg_value* regs = NULL;
  61. static int reg_size;
  62. static reg_handle_t* head = NULL;
  63. #define DIR -25
  64. static void create_registry(void);
  65. static void open_registry(void);
  66. static void save_registry(void);
  67. static void init_registry(void);
  68. static void create_registry(void){
  69.     if(regs)
  70.     {
  71. printf("Logic error: create_registry() called with existing registryn");
  72. save_registry();
  73. return;
  74.     }
  75.     regs=(struct reg_value*)malloc(3*sizeof(struct reg_value));
  76.     regs[0].type=regs[1].type=DIR;
  77.     regs[0].name=(char*)malloc(5);
  78.     strcpy(regs[0].name, "HKLM");
  79.     regs[1].name=(char*)malloc(5);
  80.     strcpy(regs[1].name, "HKCU");
  81.     regs[0].value=regs[1].value=NULL;
  82.     regs[0].len=regs[1].len=0;
  83.     reg_size=2;
  84.     head = 0;
  85.     save_registry();
  86. }
  87. static void open_registry(void)
  88. {
  89. int fd;
  90. int i;
  91. unsigned int len;
  92. if(regs)
  93. {
  94. printf("Multiple open_registry(>n");
  95. return;
  96. }
  97. fd = open(localregpathname, O_RDONLY);
  98. if (fd == -1)
  99. {
  100.     printf("Creating new registryn");
  101.     create_registry();
  102.     return;
  103. }
  104. read(fd, &reg_size, 4);
  105. regs=(struct reg_value*)malloc(reg_size*sizeof(struct reg_value));
  106. head = 0;
  107. for(i=0; i<reg_size; i++)
  108. {
  109. read(fd,&regs[i].type,4);
  110. read(fd,&len,4);
  111. regs[i].name=(char*)malloc(len+1);
  112. if(regs[i].name==NULL)
  113. {
  114. reg_size=i+1;
  115. goto error;
  116. }
  117. read(fd, regs[i].name, len);
  118. regs[i].name[len]=0;
  119. read(fd,&regs[i].len,4);
  120. regs[i].value=(char*)malloc(regs[i].len+1);
  121. if(regs[i].value==NULL)
  122. {
  123.         free(regs[i].name);
  124. reg_size=i+1;
  125. goto error;
  126. }
  127. read(fd, regs[i].value, regs[i].len);
  128. regs[i].value[regs[i].len]=0;
  129. }
  130. error:
  131. close(fd);
  132. return;
  133. }
  134. static void save_registry(void)
  135. {
  136. int fd, i;
  137. if (!regs)
  138. init_registry();
  139. fd = open(localregpathname, O_WRONLY | O_CREAT, 00666);
  140. if (fd == -1)
  141. {
  142.     printf("Failed to open registry file '%s' for writing.n",
  143.    localregpathname);
  144.     return;
  145. }
  146. write(fd, &reg_size, 4);
  147. for(i=0; i<reg_size; i++)
  148. {
  149.         unsigned len=strlen(regs[i].name);
  150. write(fd, &regs[i].type, 4);
  151. write(fd, &len, 4);
  152. write(fd, regs[i].name, len);
  153. write(fd, &regs[i].len, 4);
  154. write(fd, regs[i].value, regs[i].len);
  155. }
  156. close(fd);
  157. }
  158. void free_registry(void)
  159. {
  160.     reg_handle_t* t = head;
  161.     while (t)
  162.     {
  163. reg_handle_t* f = t;
  164. free(t->name);
  165. t=t->prev;
  166.         free(f);
  167.     }
  168.     head = 0;
  169.     if (regs)
  170.     {
  171.         int i;
  172. for(i=0; i<reg_size; i++)
  173. {
  174.     free(regs[i].name);
  175.     free(regs[i].value);
  176. }
  177. free(regs);
  178. regs = 0;
  179.     }
  180.     if (localregpathname != regpathname)
  181. free(localregpathname);
  182.     localregpathname = 0;
  183. }
  184. static reg_handle_t* find_handle_by_name(const char* name)
  185. {
  186. reg_handle_t* t;
  187. for(t=head; t; t=t->prev)
  188. {
  189. if(!strcmp(t->name, name))
  190. {
  191. return t;
  192. }
  193. }
  194. return 0;
  195. }
  196. static struct reg_value* find_value_by_name(const char* name)
  197. {
  198. int i;
  199. for(i=0; i<reg_size; i++)
  200. if(!strcmp(regs[i].name, name))
  201. return regs+i;
  202. return 0;
  203. }
  204. static reg_handle_t* find_handle(int handle)
  205. {
  206. reg_handle_t* t;
  207. for(t=head; t; t=t->prev)
  208. {
  209. if(t->handle==handle)
  210. {
  211. return t;
  212. }
  213. }
  214. return 0;
  215. }
  216. static int generate_handle()
  217. {
  218. static unsigned int zz=249;
  219. zz++;
  220. while((zz==HKEY_LOCAL_MACHINE) || (zz==HKEY_CURRENT_USER))
  221. zz++;
  222. return zz;
  223. }
  224. static reg_handle_t* insert_handle(long handle, const char* name)
  225. {
  226. reg_handle_t* t;
  227. t=(reg_handle_t*)malloc(sizeof(reg_handle_t));
  228. if(head==NULL)
  229. {
  230. t->prev=0;
  231. }
  232. else
  233. {
  234. head->next=t;
  235. t->prev=head;
  236. }
  237. t->next=0;
  238. t->name=(char*)malloc(strlen(name)+1);
  239. strcpy(t->name, name);
  240. t->handle=handle;
  241. head=t;
  242. return t;
  243. }
  244. static char* build_keyname(long key, const char* subkey)
  245. {
  246. char* full_name;
  247. reg_handle_t* t;
  248.         if((t=find_handle(key))==NULL)
  249. {
  250. TRACE("Invalid keyn");
  251. return NULL;
  252. }
  253. if(subkey==NULL)
  254. subkey="<default>";
  255. full_name=(char*)malloc(strlen(t->name)+strlen(subkey)+10);
  256. strcpy(full_name, t->name);
  257. strcat(full_name, "\");
  258. strcat(full_name, subkey);
  259. return full_name;
  260. }
  261. static struct reg_value* insert_reg_value(int handle, const char* name, int type, const void* value, int len)
  262. {
  263. reg_handle_t* t;
  264. struct reg_value* v;
  265. char* fullname;
  266. if((fullname=build_keyname(handle, name))==NULL)
  267. {
  268. TRACE("Invalid handlen");
  269. return NULL;
  270. }
  271. if((v=find_value_by_name(fullname))==NULL)
  272. //creating new value in registry
  273. {
  274. if(regs==NULL)
  275.     create_registry();
  276. regs=(struct reg_value*)realloc(regs, sizeof(struct reg_value)*(reg_size+1));
  277. //regs=(struct reg_value*)my_realloc(regs, sizeof(struct reg_value)*(reg_size+1));
  278. v=regs+reg_size;
  279. reg_size++;
  280. }
  281. else
  282. //replacing old one
  283. {
  284.     free(v->value);
  285.     free(v->name);
  286. }
  287. TRACE("RegInsert '%s'  %p  v:%d  len:%dn", name, value, *(int*)value, len);
  288. v->type=type;
  289. v->len=len;
  290. v->value=(char*)malloc(len);
  291. memcpy(v->value, value, len);
  292. v->name=(char*)malloc(strlen(fullname)+1);
  293. strcpy(v->name, fullname);
  294.         free(fullname);
  295. save_registry();
  296. return v;
  297. }
  298. static void init_registry(void)
  299. {
  300. TRACE("Initializing registryn");
  301. // can't be free-ed - it's static and probably thread
  302. // unsafe structure which is stored in glibc
  303. #ifdef MPLAYER
  304. regpathname = get_path("registry");
  305. localregpathname = regpathname;
  306. #else
  307. // regpathname is an external pointer
  308.         //
  309. // registry.c is holding its own internal pointer
  310. // localregpathname  - which is being allocate/deallocated
  311. if (localregpathname == NULL)
  312. {
  313.             const char* pthn = regpathname;
  314.     if (!regpathname)
  315.     {
  316. // avifile - for now reading data from user's home
  317. struct passwd* pwent;
  318. pwent = getpwuid(geteuid());
  319.                 pthn = pwent->pw_dir;
  320.     }
  321.     localregpathname = (char*)malloc(strlen(pthn)+20);
  322.     strcpy(localregpathname, pthn);
  323.     strcat(localregpathname, "/.registry");
  324. }
  325. #endif
  326. open_registry();
  327. insert_handle(HKEY_LOCAL_MACHINE, "HKLM");
  328. insert_handle(HKEY_CURRENT_USER, "HKCU");
  329. }
  330. static reg_handle_t* find_handle_2(long key, const char* subkey)
  331. {
  332. char* full_name;
  333. reg_handle_t* t;
  334.         if((t=find_handle(key))==NULL)
  335. {
  336. TRACE("Invalid keyn");
  337. return (reg_handle_t*)-1;
  338. }
  339. if(subkey==NULL)
  340. return t;
  341. full_name=(char*)malloc(strlen(t->name)+strlen(subkey)+10);
  342. strcpy(full_name, t->name);
  343. strcat(full_name, "\");
  344. strcat(full_name, subkey);
  345. t=find_handle_by_name(full_name);
  346. free(full_name);
  347. return t;
  348. }
  349. long __stdcall RegOpenKeyExA(long key, const char* subkey, long reserved, long access, int* newkey)
  350. {
  351.     char* full_name;
  352.     reg_handle_t* t;
  353.     struct reg_value* v;
  354.     TRACE("Opening key %sn", subkey);
  355.     if(!regs)
  356.         init_registry()
  357. ;
  358. /* t=find_handle_2(key, subkey);
  359. if(t==0)
  360. return -1;
  361. if(t==(reg_handle_t*)-1)
  362. return -1;
  363. */
  364.     full_name=build_keyname(key, subkey);
  365.     if(!full_name)
  366.         return -1;
  367.     TRACE("Opening key Fullname %sn", full_name);
  368.     v=find_value_by_name(full_name);
  369.     t=insert_handle(generate_handle(), full_name);
  370.     *newkey=t->handle;
  371.     free(full_name);
  372.     return 0;
  373. }
  374. long __stdcall RegCloseKey(long key)
  375. {
  376.     reg_handle_t *handle;
  377.     if(key==(long)HKEY_LOCAL_MACHINE)
  378. return 0;
  379.     if(key==(long)HKEY_CURRENT_USER)
  380. return 0;
  381.     handle=find_handle(key);
  382.     if(handle==NULL)
  383. return 0;
  384.     if(handle->prev)
  385. handle->prev->next=handle->next;
  386.     if(handle->next)
  387. handle->next->prev=handle->prev;
  388.     free(handle->name);
  389.     if(handle==head)
  390. head=head->prev;
  391.     free(handle);
  392.     return 1;
  393. }
  394. long __stdcall RegQueryValueExA(long key, const char* value, int* reserved, int* type, int* data, int* count)
  395. {
  396.     struct reg_value* t;
  397.     char* c;
  398.     TRACE("Querying value %sn", value);
  399.     if(!regs)
  400. init_registry();
  401.     c=build_keyname(key, value);
  402.     if (!c)
  403. return 1;
  404.     t=find_value_by_name(c);
  405.     free(c);
  406.     if (t==NULL)
  407. return 2;
  408.     if (type)
  409. *type=t->type;
  410.     if (data)
  411.     {
  412. memcpy(data, t->value, (t->len<*count)?t->len:*count);
  413. TRACE("returning %d bytes: %dn", t->len, *(int*)data);
  414.     }
  415.     if(*count<t->len)
  416.     {
  417. *count=t->len;
  418. return ERROR_MORE_DATA;
  419.     }
  420.     else
  421.     {
  422. *count=t->len;
  423.     }
  424.     return 0;
  425. }
  426. long __stdcall RegCreateKeyExA(long key, const char* name, long reserved,
  427.      void* classs, long options, long security,
  428.      void* sec_attr, int* newkey, int* status)
  429. {
  430.     reg_handle_t* t;
  431.     char* fullname;
  432.     struct reg_value* v;
  433.     //        TRACE("Creating/Opening key %sn", name);
  434.     if(!regs)
  435. init_registry();
  436.     fullname=build_keyname(key, name);
  437.     if (!fullname)
  438. return 1;
  439.     TRACE("Creating/Opening key %sn", fullname);
  440.     v=find_value_by_name(fullname);
  441.     if(v==NULL)
  442.     {
  443. int qw=45708;
  444. v=insert_reg_value(key, name, DIR, &qw, 4);
  445. if (status) *status=REG_CREATED_NEW_KEY;
  446. // return 0;
  447.     }
  448.     t=insert_handle(generate_handle(), fullname);
  449.     *newkey=t->handle;
  450.     free(fullname);
  451.     return 0;
  452. }
  453. /*
  454. LONG RegEnumValue(
  455.   HKEY hKey,              // handle to key to query
  456.   DWORD dwIndex,          // index of value to query
  457.   LPTSTR lpValueName,     // address of buffer for value string
  458.   LPDWORD lpcbValueName,  // address for size of value buffer
  459.   LPDWORD lpReserved,     // reserved
  460.   LPDWORD lpType,         // address of buffer for type code
  461.   LPBYTE lpData,          // address of buffer for value data
  462.   LPDWORD lpcbData        // address for size of data buffer
  463. );
  464. */
  465. long __stdcall RegEnumValueA(HKEY hkey, DWORD index, LPSTR value, LPDWORD val_count,
  466.    LPDWORD reserved, LPDWORD type, LPBYTE data, LPDWORD count)
  467. {
  468.     // currenly just made to support MSZH & ZLIB
  469.     //printf("Reg Enum 0x%x %d  %s %d   data: %p %d  %d >%s<n", hkey, index,
  470.     //       value, *val_count, data, *count, reg_size, data);
  471.     reg_handle_t* t = find_handle(hkey);
  472.     if (t && index < 10)
  473.     {
  474. struct reg_value* v=find_value_by_name(t->name);
  475. if (v)
  476. {
  477.     memcpy(data, v->value, (v->len < *count) ? v->len : *count);
  478.     if(*count < v->len)
  479. *count = v->len;
  480.     if (type)
  481. *type = v->type;
  482.     //printf("Found handle  %sn", v->name);
  483.     return 0;
  484. }
  485.     }
  486.     return ERROR_NO_MORE_ITEMS;
  487. }
  488. long __stdcall RegSetValueExA(long key, const char* name, long v1, long v2, const void* data, long size)
  489. {
  490.     struct reg_value* t;
  491.     char* c;
  492.     TRACE("Request to set value %s %dn", name, *(const int*)data);
  493.     if(!regs)
  494. init_registry();
  495.     c=build_keyname(key, name);
  496.     if(c==NULL)
  497. return 1;
  498.     insert_reg_value(key, name, v2, data, size);
  499.     free(c);
  500.     return 0;
  501. }
  502. long __stdcall RegEnumKeyExA(HKEY hKey, DWORD dwIndex, LPSTR lpName, LPDWORD lpcbName,
  503.    LPDWORD lpReserved, LPSTR lpClass, LPDWORD lpcbClass,
  504.    LPFILETIME lpftLastWriteTime)
  505. {
  506.     return ERROR_NO_MORE_ITEMS;
  507. }