This is the mail archive of the
cygwin-developers
mailing list for the Cygwin project.
Re: Avoid collisions between parallel installations of Cygwin
- From: Charles Wilson <cygwin at cwilson dot fastmail dot fm>
- To: cygwin-developers at cygwin dot com
- Date: Tue, 13 Oct 2009 14:02:51 -0400
- Subject: Re: Avoid collisions between parallel installations of Cygwin
cgf wrote:
> So, while it might be neat to put these in the resource section, isn't
> that normally ASCII data? Or is it binary too? It's been too long
> since I played with that.
No, you can store binary data in a resource section using RCDATA. It's a
bit tricky to store streams of bytes (other than strings), but it can be
done. And WORDs or DWORDs are easy, although you have to worry about
alignment when switching between data types (the entire RCDATA resource
will be DWORD aligned to start with).
windres -o foo_res.o -i foo_res.rc
gcc -o foo.o -c foo.c
gcc -o foo.exe foo.o foo_res.o
./foo.exe
If we add the discussed functionality and make it an option, it makes
sense to me to do it using resources ('course we'd need to provide a
(native win32) user tool to manipulate it). That way, it can be
interpreted by cygwin exactly once on load with no additional disk
access, and there's no question about changing (say /bin/.cygwinrc)
while the DLL is loaded and wondering why it hasn't taken effect -- in
this case, while the DLL is loaded you can't modify it.
And...by changing the DLL, you change its checksum so we could easily
distinguish a modified DLL from the real distributed ones, even without
the manipulation tool. Just compare md5sums.
It seems to me that this sort of thing is very different from the type
of stuff we use the CYGWIN variable for...
--
Chuck
#include <stdlib.h>
#include <stdio.h>
#include <windows.h>
#define CYGPROPS_RES_NAME "cygprops"
#define CYGPROPS_STRUCT_VERSION 0x00000001
typedef struct _cygprops {
unsigned short allow_multiple;
unsigned short something_else;
unsigned short extra_sz; /* size of byte array, below */
unsigned char *extra; /* must be even; extend to extra_sz+1 if needed */
} cygprops_t;
cygprops_t cygprops = { 0, 0, 0, NULL };
void * readres_ushort(void *addr, unsigned short *val)
{
unsigned short * p = (unsigned short *) addr;
*val = *p++;
return (void *) p;
}
void * readres_uchars_bswap(void *addr, unsigned int cnt, unsigned char *val)
{
unsigned char * p = (unsigned char *) addr;
unsigned char a,b;
int i;
for (i = 0; i < cnt; )
{
a = *p++;
b = *p++;
i += 2;
*val++ = b;
*val++ = a;
}
return (void *) p;
}
void load_props(void)
{
int i;
LPVOID lpcygprops;
unsigned short cygprops_version;
// Load toolbar resource.
HMODULE hMod = GetModuleHandle(NULL);
HGLOBAL hglb = LoadResource(hMod, FindResource(hMod, CYGPROPS_RES_NAME, RT_RCDATA));
lpcygprops = LockResource(hglb);
lpcygprops = readres_ushort(lpcygprops, &cygprops_version);
if (cygprops_version != CYGPROPS_STRUCT_VERSION)
{
fprintf(stderr, "bad cygprops version; expected %d got %d\n",
CYGPROPS_STRUCT_VERSION, cygprops_version);
exit (1);
}
lpcygprops = readres_ushort(lpcygprops, &cygprops.allow_multiple);
lpcygprops = readres_ushort(lpcygprops, &cygprops.something_else);
lpcygprops = readres_ushort(lpcygprops, &cygprops.extra_sz);
cygprops.extra = (unsigned char *) malloc (cygprops.extra_sz & 0x01
? cygprops.extra_sz + 1
: cygprops.extra_sz);
lpcygprops = readres_uchars_bswap(lpcygprops, cygprops.extra_sz, cygprops.extra);
UnlockResource (hglb);
FreeResource (hglb);
}
void destroy_props(void)
{
if (cygprops.extra)
{
free(cygprops.extra);
cygprops.extra = NULL;
}
}
void print_cygprops(void)
{
int i;
unsigned char *p;
printf("allow_multiple: 0x%04x\n", cygprops.allow_multiple);
printf("something_else: 0x%04x\n", cygprops.something_else);
printf("extra_sz : 0x%04x\n", cygprops.extra_sz);
printf("extra :");
if (cygprops.extra)
{
for (i = 0, p = cygprops.extra; i < cygprops.extra_sz; i++)
printf(" 0x%02x", *p++);
printf("\n");
}
else
printf(" <NULL>\n");
}
int main(int argc, char *argv[])
{
printf("BEFORE: \n");
print_cygprops();
printf("AFTER: \n");
load_props();
print_cygprops();
destroy_props();
return 0;
}