Porting Across UNIX and Win32 
by Abdul Sakib Mondal

Example 1:

#ifdef WIN32
VOID ServiceStart (DWORD argc, LPTSTR *argv) 
#endif
#ifdef UNIX
int main(int argc,char *argv[])
#endif
{
/**Main work is done here**/
}


Listing One
/***************CODE FOR SUN OS**********************************/
/* The kvm routines are used to read certain information from the kernel */
kvm_t *mptr;                /* Pointer to kmem */
struct proc *process;       /* Pointer to proc structure */
struct user *user;          /* Pointer to user structure */
struct file ofile;          /* File structure of an object */
struct file *fileptr;       /* Pointer to above structure */
struct ucred credits;       /* Process credentials */
/*Open /dev/kmem */
if (!(mptr = kvm_open((char *)0, (char *)0, (char *)0,O_RDONLY,
(char *)0 ))) exit (-1);

/*read process-structure of the process with pid what->proc_nr*/
process = kvm_getproc(mptr, what->proc_nr);

/* read the credentials of the process  */
if(kvm_read(mptr, process->p_cred, (char *)&credits, 
sizeof (credits)) != sizeof (credits)){
exit(-1);
}
/*you can verify for effective and real uids and gids, and user 
groups of the process using members cr_uid, cr_gid, cr_ruid, 
cr_rgid, cr_groups[] of credits */
/*Given a file/socket descriptor (what->sock_nr), if you want to 
determine properties of the corresponding object, you need to read
the ofile structure of the object, but for this you have to first 
read user structure from the kernel */
if((user = kvm_getu(mptr, process)) == NULL){
exit(-1);
}
/*Now, read the ofile structure */
if (what->sock_nr < NOFILE_IN_U) {/* if the  file structure is in 
the user-area */
if(kvm_read(mptr, user->u_ofile_arr[what->sock_nr], 
(char *) &ofile, sizeof (struct file)) != 
sizeof (struct file)){
        exit(-1);
    }
}
else/* if the  file structure is not in the user-area */{
if (kvm_read(mptr, (user->u_ofile + ((what->sock_nr - 
NOFILE_IN_U) * sizeof (struct file *))),(char *) 
&fileptr, sizeof (struct file *)) != 
sizeof (struct file *)){
        exit(-1);
}
if (kvm_read(mptr, fileptr, (char *) &ofile, 
sizeof (struct file)) != sizeof (struct file)){
        exit(-1);
}
}
/* Now we can use the structure to extract further details of the object 
(example type of the object, permissions, group owner etc. if the object is 
file, port, domain, protocol etc. if the object is socket etc.)*/
/******************CODE FOR LINUX***********************************/
* Unlike SUN OS where, task structures are maintained as linked list*       
* Linux  keeps an array of entires for task structures.  Additional *
* information (such as files opened etc.) are available through a   *
* pointer in the entry.                                             *
*********************************************************************/
#define __KERNEL__ 
#define TASK 0x001d61f4
#ifdef OLDLNUX
#define FD0 ((char *)&ts.files->fd[0] - (char *)&ts)
    #define AD(fd) (task_addr +FD0+4*(fd))
#else
    #define FILES ((char *)&ts.files - (char *)&ts)
    #define FD0 ((char *)&fs.fd[0] - (char *)&fs)
    #define AD(fd) (readvalz(task_addr +FILES)+FD0+4*(fd))
#endif
int kfd;                    /* File Pointer to /dev/kmem */
int task_addr;      
struct task_struct ts;      /*task structure*/  
struct files_struct fs;     /*file system structure*/
struct file ofile;          /*File structure of an object */
struct file *fileptr;       /*Pointer to above structure */
struct uid_credit{          /*process credential*/
    unsigned short uid,euid,suid,fsuid;
    unsigned short gid,egid,sgid,fsgid;
}credits;
int procgrps[NGROUPS];  /*process groups*/
/*******************************************************************
*   read an entry from the array in symbol table                   *
********************************************************************/  
int readval(int ad){
    int val,r;
    if (lseek(kfd,ad,SEEK_SET)<0){
        perror("lseek"); exit(1);
    }
    if((r=read(kfd,&val,4))!=4){
        if (r<0) perror("read");
        else fprintf(stderr,"Error reading ..\n");
        exit(1);
    }
    return val;
}
/*******************************************************************
*   read value at specified location, error if value is 0          *
********************************************************************/
int readvalz(int ad){
    int r=readval(ad);
    if(r==0) fprintf(stderr,"Error reading ..\n");
    return r;
}
/********************************************************************
* to read the additional information, we require the id of the      * 
* process corresponding to this entry                               *
*********************************************************************/
void readtask(int ad){
 int r;
 if (lseek(kfd,ad,SEEK_SET)<0)
        perror("lseek"), exit(1);
 if((r=read(kfd,&ts,sizeof(struct task_struct)))!=sizeof(struct task_struct)){
        if (r<0) perror("read");
        else fprintf(stderr,"Error reading ..\n");
        exit(1);
 }
}
/*******************************************************************
*   find the task structure of specified process                   *
********************************************************************/  
void findtask(int pid){
    int kadr;
    for(kadr=TASK;;kadr+=4){
/*TASK is starting address for symbol table: differs from installation to 
 * installation. Its value can be found from /boot/System.map */
        if (kadr>=TASK+4*NR_TASKS){ 
/*NR_TASK indicates number of tasks*/ 
            fprintf(stderr,"Proc not found ..\n"); 
        }       
        task_addr=readval(kadr);
        readtask(task_addr);
        if (ts.pid==pid) break;
    }
}
/*******************************************************************
*   read process credentials                                       *
********************************************************************/
void readcred(struct uid_credit *credits){
    int r;
    int ad= task_addr +(char *)&ts.uid-(char *)&ts;
    if (lseek(kfd,ad,SEEK_SET)<0)
        perror("lseek"), exit(1);
    if((r=read(kfd,credits,sizeof(struct uid_credit)))!=
                                             sizeof(struct uid_credit)){
        if (r<0) perror("read");
        else fprintf(stderr,"Error reading ..\n");
        exit(1);
    }
}
/*******************************************************************
*   read process user groups                                       *
********************************************************************/
void readgroups(int *procgrps){
    int r;
    int ad= task_addr +(char *)&ts.groups[0]-(char *)&ts;
    if (lseek(kfd,ad,SEEK_SET)<0)
        perror("lseek"), exit(1);
    if((r=read(kfd,procgrps,NGROUPS*sizeof(int)))!=NGROUPS*sizeof(int)){
        if (r<0) perror("read");
        else fprintf(stderr,"Error reading ..\n");
        exit(1);
    }
}
/*******************************************************************
*   read file structure for a given kernel object                  *
********************************************************************/
void readfile(int sock_nr, struct file *fileptr){
    int r;
    int ad=AD(sock_nr);
    if (lseek(kfd,ad,SEEK_SET)<0)
        perror("lseek"), exit(1);
if((r=read(kfd,(char *)fileptr,sizeof(struct files_struct)
))!=sizeof(struct files_struct)){
        if (r<0) perror("read");
        else fprintf(stderr,"Error reading ..\n");
        exit(1);
    }
}
kfd=open("/dev/kmem",O_RDONLY); 
if (kfd<0) { perror("open"); exit(1);}
/* read the task structure first */
findtask(what->proc_nr);
/* read the credentials of the process */
readcred(&credits);
/* read the user groups of the process*/
readgroups(procgrps); 
/*you can verify for effective and real uids and gids, and user 
groups of the process using members uid, gid, euid, egid of 
credits and procgrps */
/* read the ofile structure for the give descriptor (what->
sock_nr) */
readfile(what->sock_nr,&ofile); 
/* Now we can use the structure to extract further details of the object 
(example type of the object, permissions, group owner etc. if the object is 
file, port, domain, protocol etc. if the object is socket etc.)*/






4


