Example #1
0
/* creates a process, any time */
struct proc * alloc_proc(){
	struct proc *p;
	char *sp;
	for(p=ptable.proc;p<&ptable.proc[NPROC];p++){
		if(p->state==UNUSED){
			p->state=EMBRYO;
			p->pid=proc_count++;
			/* allocate kernel stack */
			if(!(p->kstack=(char *)kmalloc(KSTACKSIZE))){ 
				/* KSTACKSIZE IS 4096B*/
				p->state=UNUSED;
				return NULL;
			}
			sp=p->kstack+KSTACKSIZE; /* points to end of stack */
			/* make space for trapframe */
			sp-=sizeof(struct trapframe);
			p->tf=(struct trapframe *)sp;
			/* set up new context to start executing at forkret, ehich returns to trapret */
			sp-=8;
			*(uint64_t *)sp=(uint64_t)trapret;
			sp-=(sizeof(struct context));
			sp+=8;
			p->context=(struct context *)sp;
			/* clear contents of ofile array */
			memset1((char *)p->ofile,0,sizeof(struct file *)*NOFILE);
			/* clear contents of cwd */
			memset1((char *)p->cwd,0,sizeof(char)*NCHARS);
			return p;
		}
	}
	return NULL;
}
Example #2
0
uint8_t LoRaMacSend( LoRaMacHeader_t *macHdr, uint8_t *fOpts, uint8_t fPort, void *fBuffer, uint16_t fBufferSize )
{
    uint8_t retStatus;

    memset1( ( uint8_t* ) &LoRaMacEventInfo, 0, sizeof( LoRaMacEventInfo ) );

    switch( Send( macHdr, fPort, fBuffer, fBufferSize ) )
    {
        case LORAMAC_STATUS_OK:
            retStatus = 0U;
            break;
        case LORAMAC_STATUS_BUSY:
            retStatus = 1U;
            break;
        case LORAMAC_STATUS_NO_NETWORK_JOINED:
            retStatus = 2U;
            break;
        case LORAMAC_STATUS_LENGTH_ERROR:
        case LORAMAC_STATUS_MAC_CMD_LENGTH_ERROR:
            retStatus = 3U;
            break;
        case LORAMAC_STATUS_SERVICE_UNKNOWN:
            retStatus = 4U;
            break;
        case LORAMAC_STATUS_DEVICE_OFF:
            retStatus = 6U;
            break;
        default:
            retStatus = 1U;
            break;
    }

    return retStatus;
}
Example #3
0
void AES_CMAC_Final(u_int8_t digest[AES_CMAC_DIGEST_LENGTH], AES_CMAC_CTX *ctx)
{
	u_int8_t K[16];
	unsigned char in[16];
	/* generate subkey K1 */
	memset1(K, '\0', 16);

	// rijndael_encrypt(&ctx->rijndael, K, K);

	aes_encrypt( K, K, &ctx->rijndael);

	if (K[0] & 0x80)
	{
		LSHIFT(K, K);
		K[15] ^= 0x87;
	} else
		LSHIFT(K, K);

	if (ctx->M_n == 16)
	{
		/* last block was a complete block */
		XOR(K, ctx->M_last);
	} else {
		/* generate subkey K2 */
		if (K[0] & 0x80)
		{
			LSHIFT(K, K);
			K[15] ^= 0x87;
		} else
			LSHIFT(K, K);

		/* padding(M_last) */
		ctx->M_last[ctx->M_n] = 0x80;
		while (++ctx->M_n < 16)
			ctx->M_last[ctx->M_n] = 0;

		XOR(K, ctx->M_last);
	}
	XOR(ctx->M_last, ctx->X);

	// rijndael_encrypt(&ctx->rijndael, ctx->X, digest);

	memcpy1(in, &ctx->X[0], 16); //Bestela ez du ondo iten
	aes_encrypt(in, digest, &ctx->rijndael);
	memset1(K, 0, sizeof K);
}
Example #4
0
uint8_t LoRaMacSendFrameOnChannel( ChannelParams_t channel )
{
    memset1( ( uint8_t* ) &LoRaMacEventInfo, 0, sizeof( LoRaMacEventInfo ) );

    SendFrameOnChannel( channel );

    /* SendFrameOnChannel has always status "OK" */
    return 0;
}
Example #5
0
/* load initcode.S into address 0 of pml4 */
void inituvm(pml4 *pml4_t, char *star,uint64_t sz){
	char *mem;
	if(sz >= FRAME_SIZE){
		/* printf("inituvm: input sz more than a page\n"); */
		;
	}
	mem=(char *)kmalloc(FRAME_SIZE);
	memset1(mem,0,FRAME_SIZE);
	
}
Example #6
0
void LoRaMacConfirmQueueInit( LoRaMacPrimitives_t* primitives )
{
    Primitives = primitives;

    // Init counter
    MlmeConfirmQueueCnt = 0;

    // Init buffer
    BufferStart = MlmeConfirmQueue;
    BufferEnd = MlmeConfirmQueue;

    memset1( (uint8_t*) MlmeConfirmQueue, 0xFF, sizeof( MlmeConfirmQueue ) );

    // Common status
    CommonStatus = LORAMAC_EVENT_INFO_STATUS_ERROR;
}
Example #7
0
pml4 *load_kern_vm(){
	/* allocate a pml4 entry. load kernel vm into pml4 entry and return it */
	pml4 *pml4_t;
	if(!(pml4_t=(pml4 *)kmalloc(FRAME_SIZE))){
		return NULL;
	}
	memset1((char *)pml4_t,0,FRAME_SIZE);
	
	/* put kernel space which is marked RW for only supervisor into process pml4 table */
	/* pml4_base is a physical addr of 0x100000. */
	/* to derefernce pml4 entries. conver the physical address into virt addr  and then dereference it*/
	
	pml4_t->m_entries[511]=((pml4 *)get_virt_addr((uint64_t)pml4_base))->m_entries[511];
	return pml4_t;
	
}
Example #8
0
uint8_t LoRaMacSendConfirmedFrame( uint8_t fPort, void *fBuffer, uint16_t fBufferSize, uint8_t nbRetries )
{
    MibRequestConfirm_t mibGet;
    McpsReq_t mcpsRequest;
    uint8_t retStatus;

    memset1( ( uint8_t* )&LoRaMacEventInfo, 0, sizeof( LoRaMacEventInfo ) );

    mibGet.Type = MIB_CHANNELS_DATARATE;
    LoRaMacMibGetRequestConfirm( &mibGet );

    mcpsRequest.Type = MCPS_CONFIRMED;
    mcpsRequest.Req.Confirmed.fBuffer = fBuffer;
    mcpsRequest.Req.Confirmed.fBufferSize = fBufferSize;
    mcpsRequest.Req.Confirmed.fPort = fPort;
    mcpsRequest.Req.Confirmed.nbRetries = nbRetries;
    mcpsRequest.Req.Confirmed.Datarate = mibGet.Param.ChannelsDatarate;

    switch( LoRaMacMcpsRequest( &mcpsRequest ) )
    {
        case LORAMAC_STATUS_OK:
            retStatus = 0U;
            break;
        case LORAMAC_STATUS_BUSY:
            retStatus = 1U;
            break;
        case LORAMAC_STATUS_NO_NETWORK_JOINED:
            retStatus = 2U;
            break;
        case LORAMAC_STATUS_LENGTH_ERROR:
        case LORAMAC_STATUS_MAC_CMD_LENGTH_ERROR:
            retStatus = 3U;
            break;
        case LORAMAC_STATUS_SERVICE_UNKNOWN:
            retStatus = 4U;
            break;
        case LORAMAC_STATUS_DEVICE_OFF:
            retStatus = 6U;
            break;
        default:
            retStatus = 1U;
            break;
    }

    return retStatus;
}
Example #9
0
void AES_CMAC_Init(AES_CMAC_CTX *ctx)
{
	memset1(ctx->X, 0, sizeof ctx->X);
	ctx->M_n = 0;
	memset1(ctx->rijndael.ksch, '\0', 240);
}
Example #10
0
File: fs.c Project: jjhlzn/haribote
void mkfs()
{
	MESSAGE driver_msg;
	int i, j;

	int bits_per_sect = SECTOR_SIZE * 8; /* 8 bits per byte */
	
	struct MEMMAN *memman = (struct MEMMAN *) MEMMAN_ADDR;
	fsbuf = (u8 *)memman_alloc(memman,FSBUF_SIZE);

	/* get the geometry of ROOTDEV */
	struct part_info geo;
	//driver_msg.type		= DEV_IOCTL;
	//driver_msg.DEVICE	= MINOR(ROOT_DEV);
	//driver_msg.REQUEST	= DIOCTL_GET_GEO;
	//driver_msg.BUF		= &geo;
	//driver_msg.PROC_NR	= 0; //TASK_FS
	//hd_ioctl(&driver_msg);
	geo.size = 20097;
	
	debug("dev size: 0x%x sectors", geo.size);

	/************************/
	/*      super block     */
	/************************/
	struct super_block sb;
	sb.magic	  = MAGIC_V1;
	sb.nr_inodes	  = bits_per_sect;  //512 * 8 = 4096个i_node
	sb.nr_inode_sects = sb.nr_inodes * INODE_SIZE / SECTOR_SIZE;  //i_node所占用的扇区数=4096 * 32 / 512 = 32
	sb.nr_sects	  = geo.size; /* partition size in sector, 这个分区总共有多少个扇区 */
	sb.nr_imap_sects  = 1; //inode-map所占用的扇区数
	sb.nr_smap_sects  = sb.nr_sects / bits_per_sect + 1; //secotr-map所占用的扇区数
	sb.n_1st_sect	  = 1 + 1 +   /* boot sector & super block */
						sb.nr_imap_sects + sb.nr_smap_sects + sb.nr_inode_sects; //数据区的第一个扇区编号
	sb.root_inode	  = ROOT_INODE;  //root directory占用的inode编号
	sb.inode_size	  = INODE_SIZE; 
	struct inode x;
	sb.inode_isize_off= (int)&x.i_size - (int)&x; //i_size在i-node结构中的偏移
	sb.inode_start_off= (int)&x.i_start_sect - (int)&x; //start_sect在i-node结构中的偏移
	sb.dir_ent_size	  = DIR_ENTRY_SIZE; //DIR_ENTRY结构的大小
	struct dir_entry de;
	sb.dir_ent_inode_off = (int)&de.inode_nr - (int)&de; //inode_nr在dir_entry中的偏移
	sb.dir_ent_fname_off = (int)&de.name - (int)&de; //name在dir_entry中的偏移

	memset1(fsbuf, 0x90, SECTOR_SIZE);
	memcpy1(fsbuf, &sb,  SUPER_BLOCK_SIZE);
	
	debug("sb.n_1st_sect = %d",sb.n_1st_sect);
	
	/* write the super block */
	WR_SECT(ROOT_DEV, 1);

	/************************/
	/*       inode map      */
	/************************/
	memset1(fsbuf, 0, SECTOR_SIZE);
	for (i = 0; i < (NR_CONSOLES + 2); i++)
		fsbuf[0] |= 1 << i;

	assert(fsbuf[0] == 0x1F);/* 0001 1111 : 
	//			  *    | ||||
	//			  *    | |||`--- bit 0 : reserved
	//			  *    | ||`---- bit 1 : the first inode,
	//			  *    | ||              which indicates `/'
	//			  *    | |`----- bit 2 : /dev_tty0
	//			  *    | `------ bit 3 : /dev_tty1
	//			  *    `-------- bit 4 : /dev_tty2
	//			  */
	WR_SECT(ROOT_DEV, 2);

	/************************/
	/*      secter map      */
	/************************/
	memset1(fsbuf, 0, SECTOR_SIZE);
	int nr_sects = NR_DEFAULT_FILE_SECTS + 1;
	/*             ~~~~~~~~~~~~~~~~~~~|~   |
	 *                                |    `--- bit 0 is reserved
	 *                                `-------- for `/'
	 */
	for (i = 0; i < nr_sects / 8; i++)
		fsbuf[i] = 0xFF;

	for (j = 0; j < nr_sects % 8; j++)
		fsbuf[i] |= (1 << j);

	WR_SECT(ROOT_DEV, 2 + sb.nr_imap_sects);

	/* zeromemory the rest sector-map */
	memset1(fsbuf, 0, SECTOR_SIZE);
	for (i = 1; i < sb.nr_smap_sects; i++)
		WR_SECT(ROOT_DEV, 2 + sb.nr_imap_sects + i);

	/************************/
	/*       inodes         */
	/************************/
	/* inode of `/' */
	memset1(fsbuf, 0, SECTOR_SIZE);
	struct inode * pi = (struct inode*)fsbuf;
	pi->i_mode = I_DIRECTORY;
	pi->i_size = DIR_ENTRY_SIZE * 4; /* 4 files:
					  * `.',
					  * `dev_tty0', `dev_tty1', `dev_tty2',
					  */
	pi->i_start_sect = sb.n_1st_sect;
	pi->i_nr_sects = NR_DEFAULT_FILE_SECTS;
	/* inode of `/dev_tty0~2' */
	for (i = 0; i < NR_CONSOLES; i++) {
		pi = (struct inode*)(fsbuf + (INODE_SIZE * (i + 1)));
		pi->i_mode = I_CHAR_SPECIAL;
		pi->i_size = 0;
		pi->i_start_sect = MAKE_DEV(DEV_CHAR_TTY, i);
		debug("pi->i_start_sect = %d",MAKE_DEV(DEV_CHAR_TTY, i));
		pi->i_nr_sects = 0;
	}
	WR_SECT(ROOT_DEV, 2 + sb.nr_imap_sects + sb.nr_smap_sects);

	/************************/
	/*          `/'         */
	/************************/
	memset1(fsbuf, 0, SECTOR_SIZE);
	struct dir_entry * pde = (struct dir_entry *)fsbuf;

	pde->inode_nr = 1;
	strcpy(pde->name, ".");

	/* dir entries of `/dev_tty0~2' */
	for (i = 0; i < NR_CONSOLES; i++) {
		pde++;
		pde->inode_nr = i + 2; /* dev_tty0's inode_nr is 2 */
		
		sprintf(pde->name, "dev_tty%d", i);
		
		debug("pde->inode_nr = %d",pde->inode_nr);
		debug("pde->name = %s",pde->name);
	}
	WR_SECT(ROOT_DEV, sb.n_1st_sect);
}
Example #11
0
/*
 * Set next transmission channel according to duty cycle boundries
 * unless it is a scheduled transmission on a specific channel (Class D)
 *
 * \return ERR_OK if a channel was set successfully
 */
static uint8_t SetNextChannel( void )
{
    uint8_t i = 0;
    uint8_t j = 0;
    uint8_t k = 0;
    uint8_t nbEnabledChannels = 0;
    uint8_t enabledChannels[LORA_MAX_NB_CHANNELS];
    TimerTime_t curTime = TimerGetCurrentTime();

    memset1(enabledChannels, 0, LORA_MAX_NB_CHANNELS);

// Update Aggregated duty cycle
    if ( AggregatedTimeOff < (curTime - AggregatedLastTxDoneTime) ) {
        AggregatedTimeOff = 0;
    }

// Update bands Time OFF
    TimerTime_t minTime = (TimerTime_t)(-1);
    for ( i = 0; i < LORA_MAX_NB_BANDS; i++ ) {
        if ( pLoRaDevice->dbgFlags.Bits.dutyCycleCtrlOff == 0 ) {
            if ( Bands[i].TimeOff < (curTime - Bands[i].LastTxDoneTime) ) {
                Bands[i].TimeOff = 0;
            }
            if ( Bands[i].TimeOff != 0 ) {
                minTime = MIN(Bands[i].TimeOff, minTime);
            }
        } else {
            minTime = 0;
            Bands[i].TimeOff = 0;
        }
    }

// Search how many channels are enabled
    for ( i = 0, k = 0; i < LORA_MAX_NB_CHANNELS; i += 16, k++ ) {
        for ( j = 0; j < 16; j++ ) {
            if ( (pLoRaDevice->channelsMask[k] & (1 << j)) != 0 ) {
                if ( Channels[i + j].Frequency == 0 ) {   // Check if the channel is enabled
                    continue;
                }
                if ( ((Channels[i + j].DrRange.Fields.Min <= pLoRaDevice->currChannelIndex)
                        && (pLoRaDevice->currDataRateIndex <= Channels[i + j].DrRange.Fields.Max))
                        == false ) {   // Check if the current channel selection supports the given datarate
                    continue;
                }
                if ( Bands[Channels[i + j].Band].TimeOff > 0 ) {   // Check if the band is available for transmission
                    continue;
                }
                if ( AggregatedTimeOff > 0 ) {   // Check if there is time available for transmission
                    continue;
                }
                enabledChannels[nbEnabledChannels++] = i + j;
            }
        }
    }
    if ( nbEnabledChannels > 0 ) {
        pLoRaDevice->currChannelIndex = enabledChannels[randr(0, nbEnabledChannels - 1)];
        return 0;
    }

    return ERR_OK;
}
Example #12
0
/* creates the first process */
void userinit(){
	struct proc *p;
	/* printf("entered userinit\n"); */
	/* allocate memory for stdin wait queue */
	_stdin = (struct read_proc*)kmalloc(sizeof(struct read_proc));
	memset1((char *)_stdin,0,sizeof(struct read_proc));
	memset1((char *)ptable.proc,0,sizeof(ptable));
	p=alloc_proc();
	initproc=p;
	fgproc=initproc;
	if(!(p->pml4_t=load_kern_vm())){
		/* panic code goes here*/
		printf("Kernel Panic: Unable To Create Initproc\n");
	}
	//inituvm(p->pml4_t,binary_initcode_start,binary_initcode_size);
	p->size=FRAME_SIZE;
	/* clear the trapframe. this is only done for fist process */
	memset1((char *)p->tf,0,sizeof(struct trapframe));
	/* p->tf->cs=0x8/\* SEG_KCS() *\/;			/\* kernel code segment *\/ */
	/* p->tf->ss=0x10/\* SEG_KDS() *\/;			/\* kernel data segment *\/ */
	p->tf->cs=0x1B;			/* user code segment */
	p->tf->ss=0x23;			/* user data segment */
	p->tf->rflags=FL_IF;			/* enable interrupts */
	
	/* rsp will be sey in exec */
	/* p->tf->rsp=FRAME_SIZE; /\* where does the user stack star from in the proc vm *\/ */

	/* rip will be set in exec */
	/* p->tf->rip=0;		   /\* begining of initcode.S *\/ */

	strcpy(p->name,"initcode");	/* p->name has a size of 32 bytes */
	p->state=RUNNABLE;
	
	
	/* printf("calling exec\n"); */
	
	/* call exec */
	proc=p;
	/* set cwd of initproc to root '/' */
	strcpy(proc->cwd,"/");

	char *a="bin/hello";
	char *argv[3];
	argv[0]=a;argv[1]="os/sbunix";argv[2]=NULL;
	char *envp[7];
	envp[0]="PATH=/bin";
	envp[1]="envp1";
	envp[2]="envp2";
	envp[3]="envp3";
	envp[4]="envp4";
	envp[5]="envp5";
	envp[6]=NULL;
	cli();

	exec("bin/hello",argv,envp);
	//p->tf->cs=(SEG_);
	/* ltr(0x2Bu); */
	/* ltr 0x2B   with RPL of 3 for user??? */
	ltr(0x2Bu);

	/* set WP bit in cr0 */
	set_wp_bit();


	/* clear ftable */
	memset1((char *)ftable.file,0,sizeof(struct file)*NFILE);
	/* clear file descriptor table of proc,i.e initproc */
	int fd=0;
	for(fd=0;fd<NOFILE;fd++){
		proc->ofile[fd]=NULL;
	}
	struct file *fp=NULL;
	/* give initproc STDIN, STDOUT,STDERR*/
	proc->ofile[STDIN]=filealloc();
	if(proc->ofile[STDIN]==NULL){
		printf("Kernel Panic, STDIN fiel struct not allocd for initproc\n");
		/* panic. kill proc */
	}
	fp=proc->ofile[STDIN];
	fp->type=FD_STDIN;
	fp->readable=1;	/* mark readable */
	fp->writable=0;	/* mark not writable */

	proc->ofile[STDOUT]=filealloc();
	if(proc->ofile[STDOUT]==NULL){
		printf("Kernel Panic: STDOUT file struct not allocd for initproc\n");
		/* panic. kill proc */
	}
	fp=proc->ofile[STDOUT];
	fp->type=FD_STDOUT;
	fp->readable=0;	/* mark NOT readable */
	fp->writable=1;	/* mark writable */


	proc->ofile[STDERR]=filealloc();
	if(proc->ofile[STDERR]==NULL){
		printf("Kernel Panic: STDERR fiel struct not allocd for initproc\n");
		/* panic. kill proc */
	}
	fp=proc->ofile[STDERR];
	fp->type=FD_STDERR;
	fp->readable=0;	/* mark NOT readable */
	fp->writable=1;	/* mark  writable */


	/* initialize sleep_head and sleep_tail to NULL */
	init_sleep_queue();
	init_waitpid_queue();
	init_stdin_queue();

	/* initialize inodes */
	/* init_inodes(); */
	/* printf writes to <1MB mem region. Now user page tables are loaded. We cannot access <1MB since we did not map that region into user process < 1MB VM aread */
	/* printf("calling scheduler\n"); */
	scheduler();
}
Example #13
0
HRESULT BasicFileOpen(PWSTR* filePath)
{
	// CoCreate the File Open Dialog object.
	IFileDialog *pfd = NULL;
	HRESULT hr = CoCreateInstance(CLSID_FileOpenDialog, 
		NULL, 
		CLSCTX_INPROC_SERVER, 
		IID_PPV_ARGS(&pfd));
	if (SUCCEEDED(hr))
	{
		// Create an event handling object, and hook it up to the dialog.
		IFileDialogEvents *pfde = NULL;
		//DWORD dwCookie;
		// Set the options on the dialog.
		DWORD dwFlags;

		// Before setting, always get the options first in order 
		// not to override existing options.
		hr = pfd->GetOptions(&dwFlags);
		if (SUCCEEDED(hr))
		{
			// In this case, get shell items only for file system items.
			hr = pfd->SetOptions(dwFlags | FOS_FORCEFILESYSTEM);
			if (SUCCEEDED(hr))
			{
				static const COMDLG_FILTERSPEC c_rgSaveTypes[] =
				{
					{L"Executable Files(*.exe)",       L"*.exe"},
				};
				// Set the file types to display only. 
				// Notice that this is a 1-based array.
				hr = pfd->SetFileTypes(ARRAYSIZE(c_rgSaveTypes), c_rgSaveTypes);
				if (SUCCEEDED(hr))
				{
					// Set the selected file type index to Word Docs for this example.
					hr = pfd->SetFileTypeIndex(1);
					if (SUCCEEDED(hr))
					{
						// Set the default extension to be ".doc" file.
						hr = pfd->SetDefaultExtension(L"exe");
						if (SUCCEEDED(hr))
						{
							// Show the dialog
							hr = pfd->Show(g_hwnd);
							if (SUCCEEDED(hr))
							{
								// Obtain the result once the user clicks 
								// the 'Open' button.
								// The result is an IShellItem object.
								IShellItem *psiResult;
								hr = pfd->GetResult(&psiResult);
								if (SUCCEEDED(hr))
								{
									// We are just going to print out the 
									// name of the file for sample sake.
									PWSTR pszFilePath = NULL;
									hr = psiResult->GetDisplayName(SIGDN_FILESYSPATH, 
										&pszFilePath);
									if (SUCCEEDED(hr))
									{
										*filePath=pszFilePath;
										
									}
									psiResult->Release();
								}
							}
						}
					}
				}
			}
		}
		pfd->Release();
	}
	else
	{
		hr=E_OUTOFMEMORY;
		OPENFILENAME ofn;
		LPWSTR pszFile=(LPWSTR)CoTaskMemAlloc(260*2);
		if(pszFile!=NULL)
		{
			memset1(&ofn,0,sizeof(ofn));
			ofn.lStructSize = sizeof(ofn);
			ofn.hwndOwner = g_hwnd;
			ofn.lpstrFile = pszFile;
			// Set lpstrFile[0] to '\0' so that GetOpenFileName does not 
			// use the contents of szFile to initialize itself.
			ofn.lpstrFile[0] = L'\0';
			ofn.nMaxFile = 260;
			ofn.lpstrFilter = L"Executable Files(*.exe)\0*.exe\0";
			ofn.nFilterIndex = 1;
			ofn.lpstrFileTitle = NULL;
			ofn.nMaxFileTitle = 0;
			ofn.lpstrInitialDir = NULL;
			ofn.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST;

			if (GetOpenFileName(&ofn)==TRUE)
			{
				*filePath=pszFile;
				hr=0;
			}
		}

	}
	return hr;
}
Example #14
0
INT_PTR CALLBACK ShellProc(
  _In_  HWND hwndDlg,
  _In_  UINT uMsg,
  _In_  WPARAM wParam,
  _In_  LPARAM lParam
  )
{
	int idx;
	PWSTR exePath;
	wchar_t addrString[16];
	DWORD address;
	switch (uMsg) 
	{ 
	case WM_COMMAND: 
		switch (LOWORD(wParam)) 
		{ 
		case IDOK: 
			{
				int ccnt=GetDlgItemText(hwndDlg,IDC_ADDRESS,addrString,15);
                if(ccnt==0)
                    address=0;
				else if(!StrToIntEx(addrString,STIF_SUPPORT_HEX,(int*)&address))
				{
					MessageBox(hwndDlg,L"Function address must be a hex number.",0,0);
					break;
				}
				
				int len=GetWindowTextLength(GetDlgItem(hwndDlg,IDC_EXEPATH));

				if(len==0)
				{
					MessageBox(hwndDlg,L"Please select the exe file",0,0);
					break;
				}

				exePath=new wchar_t[len+1];
				if(exePath==0)
				{
					delete[] exePath;
					MessageBox(hwndDlg,L"Not enough memory",0,0);
					break;
				}

				GetDlgItemText(hwndDlg,IDC_EXEPATH,exePath,len+1);
				
				STARTUPINFO si;
				memset1(&si,0,sizeof(si));
				si.cb=sizeof(si);
				PROCESS_INFORMATION pi;
				if(!CreateProcess(0,exePath,0,0,FALSE,CREATE_SUSPENDED,0,0,&si,&pi))
				{
					delete[] exePath;
					MessageBox(hwndDlg,L"Can't start exe!",0,0);
					break;
				}
				delete[] exePath;

				int pathLen=256;
				wchar_t* dllPath=new wchar_t[pathLen];
				int retlen=GetModuleFileName(0,dllPath,pathLen);
				while(GetLastError()==ERROR_INSUFFICIENT_BUFFER)
				{
					delete[] dllPath;
					pathLen*=2;
					dllPath=new wchar_t[pathLen];
					retlen=GetModuleFileName(0,dllPath,pathLen);
				};
				wchar_t* p=dllPath+retlen;
				for(;p>dllPath;p--)
					if(*p==L'\\')
						break;
				*(p+1)=L'\0';
				lstrcat(dllPath,L"extractor.dll");

				int rslt=InjectToProcess(pi.hProcess,pi.hThread,dllPath,(DecoprFunc)address);
				delete[] dllPath;
				if(rslt<0)
				{
					MessageBox(hwndDlg,L"Failed to inject process",0,0);
					break;
				}

				wchar_t pipeName[30];
				wsprintf(pipeName,PIPE_NAME,pi.dwProcessId);

				HANDLE pipe=CreateNamedPipe(pipeName,PIPE_ACCESS_DUPLEX,PIPE_TYPE_BYTE|PIPE_READMODE_BYTE|PIPE_WAIT,
					PIPE_UNLIMITED_INSTANCES,256,256,0,0);

				if(pipe==INVALID_HANDLE_VALUE)
				{
					MessageBox(hwndDlg,L"Faild to create pipe",0,0);
					TerminateProcess(pi.hProcess,0);
					break;
				}
				
				ResumeThread(pi.hThread);

				rslt=PipeComm(pipe,address);
				CloseHandle(pipe);
				if(rslt<0)
				{
					MessageBox(hwndDlg,L"Failed to communicated with sub process",0,0);
					break;
				}

			}
			// Fall through. 

		case IDCANCEL: 
			EndDialog(hwndDlg, wParam); 
			return TRUE; 

		case IDC_ADDRESS:
			if(HIWORD(wParam)==EN_CHANGE)
			{
				idx=SendDlgItemMessage(hwndDlg,IDC_GAMELIST,CB_GETCURSEL,0,0);
				if(idx<g_gameCount)
				{
					int cnt=GetDlgItemText(hwndDlg,IDC_ADDRESS,addrString,15);
                    if(cnt==0)
                        SendDlgItemMessage(hwndDlg,IDC_GAMELIST,CB_SETCURSEL,0,0);
					else if(idx!=CB_ERR && !(StrToIntEx(addrString,STIF_SUPPORT_HEX,(int*)&address) && address==g_gameList[idx].funcAddress))
						SendDlgItemMessage(hwndDlg,IDC_GAMELIST,CB_SETCURSEL,-1,0);
				}
			}
			break;

		case IDC_GAMELIST:
			switch (HIWORD(wParam))
			{
			case CBN_SELCHANGE:
				idx=SendDlgItemMessage(hwndDlg,IDC_GAMELIST,CB_GETCURSEL,0,0);
                if(idx==0)
                {
                    SetDlgItemText(hwndDlg,IDC_ADDRESS,L"");
                }
				else if(idx!=CB_ERR && idx<g_gameCount)
				{
					wsprintf(addrString,L"0x%X",g_gameList[idx].funcAddress);
					SetDlgItemText(hwndDlg,IDC_ADDRESS,addrString);
				}
				break;
			}
			break;

		case IDC_BROWSE:
			if(SUCCEEDED(BasicFileOpen(&exePath)))
			{
				SetDlgItemText(hwndDlg,IDC_EXEPATH,exePath);
				CoTaskMemFree(exePath);
			}
			break;
		case IDC_ABOUT:
			MessageBox(hwndDlg,L"fxckBGI - an extractor for BGI engine.\n\tv" PRODUCT_VERSION L" by AmaF",L"About",MB_ICONINFORMATION);
			break;
		} 
		break;

	case WM_INITDIALOG:
		g_hwnd=hwndDlg;
		HICON icon=LoadIcon(g_hInstance,(LPCWSTR)IDI_ICON1);
		SendMessage(hwndDlg,WM_SETICON,ICON_SMALL,(LPARAM)icon);

        for(int i=0;i<g_gameCount;i++)
        {
            SendDlgItemMessage(hwndDlg,IDC_GAMELIST,CB_ADDSTRING,0,(LPARAM)(g_gameList[i].gameName));
        }
        SendDlgItemMessage(hwndDlg,IDC_GAMELIST,CB_SETCURSEL,0,0);
		return TRUE;
	} 
	return FALSE; 
}