三月飞雪

今天,2013年3月20日,农历二月初九,北京居然下雪了!

星期一听到新闻说星期二会下雪,还认为那不会怎么样,或者只是小雪或雨夹雪(星期二起床的时候外面就是这样的,盖着灌木的帆布上面有浅浅的白色,路面只剩下湿的痕迹)。

但是星期二晚上,雪下起来了。

九点多,我望向窗外,雪已经下起来了。那是怎么样的一场雪啊!就像去年冬天(第一场雪倒是雨夹雪),雪花从天而降,让人一看就知道,那是狂欢的雨点变成的雪花。再加上北风的吹拂(对,吹拂),雪花向着北边飘去,其间还伴随着上下的“颠簸”。在橘黄色的路灯光的映照下,那些雪花在空中划过的完美曲线都可以看得一清二楚。一片雪花飘到窗前,那真是一小片,晶莹而泛白,轻盈地荡漾着——但是,我一伸手,它就没了,只余下一丝清凉,和一滩再也普通不过的水而已。

雪花飘飘,不久柏油路就盖上了棉被。

第二天,早晨,太阳升起来了。这时的太阳,被朦胧的雪所遮挡,呈现出橘红色,可以用眼睛望着。阳光照在身上,空气不湿也不是很冷,这就是所谓“冬日的暖阳”了,阳光可以把从冰冷中拯救出来。更好看的是那天空,最靠近地平线的地方是乳白色的,向上走40°,乳白色和淡蓝色融合了。那种渐变的效果,我是很难调配出来,只有欣赏的份儿了。

这次还可以感觉到和上学期很大的不同,这次的雪非常厚(后来报道说北京最厚的有20厘米左右,我目测这里是大约15厘米)。一看就知道昨晚刮北风——一些路灯柱子或树干上,南边覆盖上了一层冰花,而北边则是秃头。这雪不仅厚,还很温柔,和风一样。树干上真的落满了雪,整根树枝都是白色的,像洒满了白糖一样,长胖了;但是这雪很完好地附着在树枝上面,就像穿上了棉衣,贴身的棉袄,一切。而这雪很忠实地反映了物体的形状——树枝,灌木丛,自行车,甚至(食堂二楼露台上的)卫星天线,尽显其柔美的特性。如果昨晚风凌厉一些,想必雪就都散了吧。

下楼的时候,又见到那些纯白的、可爱的雪了,就在没人践踏的地方,安静地躺着。就像见到久违的朋友,我对她会心一笑。

自然,我们又打雪仗了,这次的“库存”非常充足哟。

中午的时候出太阳了。我原本以为这中午的太阳会将雪摧残殆尽,不过令我没想到的是,下午还有一些雪在,有些表面还是白色的。

但是,为什么三月份(农历二月初九)还下雪呢?不知道。

分享到 评论

偶思

男孩和女孩是一对双胞胎,从小到大,他们形影不离。或者说,他们的生命就是一体的。

可是,女孩太纯洁了。他们都深知,这个世界容不下她的心灵。

于是,女孩对男孩说:“你成为神吧。”

男孩夜以继日,终于走上神坛。

男孩成为了神,处处保护着女孩。女孩很开心,她知道,在他的保护之下,她很安全。

后来,男孩带着女孩走向了一个没有人可以去到的小岛。在那里,作为神的男孩倾听着世界,而女孩则彻底得到了解放。

但是——多么奇怪啊,那里只有他们。

——“你不孤独吗?”人问。

——“是的,或者不。”男孩说。女孩浅浅地笑着,没人可以看见。

他们永生。

分享到 评论

洗“枣”记(2013年3月20日)

上个星期,靠近3号公寓楼的一棵树下的泥土池子开始冒热气。这热气,我一开始还以为是烟——谁在里面烧东西或者放了啥强氧化剂了,不久发现原来是热气。另外一个情况是,上星期澡堂热水的供应量下降了。结合这两个条件,澡堂的热水管子漏了。

既然坏了,那就要派人来修对吧。于是在星期五,楼管贴出了告示,说从3月16日(星期六)开始将关闭澡堂,重新开启的时间未知。我看到这消息之后当天晚上享受了一个不冷不热的澡,心想估计一个小破口就一天好了。可是后来的事实证明,我错了。

星期六,我去了校本部参加微电影分镜头的修订。当然,这就免不了挤两次地铁,以及在校内跑来跑去。晚上回到宿舍,这衣服的肮脏程度较平时要糟糕一些(我比较爱干净),不过我还是换了裤子,盖被子睡了。第一天不能洗澡,真是难熬啊!记得我高二的时候,是每天洗三次的,高三有所下降,也有每天两次。晚上我还是克制自己,算睡了一个安稳觉。星期天,在宿舍一天,为了让衣服不要更脏我还尽量避免下楼,一天只吃了一餐,方便面+压缩饼干。没错,当天晚上还是不能洗澡;而且我没看到任何人在坑边工作(其实他们是在下午做事)。行,凑合凑合吧。两天不洗澡,身上难受得像蚂蚁叮一样。

到了星期一,该上课了。上了一天课,还在食堂吃了一餐。最重要的是,下午上了一节体育课!还好,天气不热,没出多少汗。但是几天的“积淀”,让我弯脖子的时候有微微的粘滞感。好消息是,快到吃饭的时候,我听闻晚上可以洗澡了,不过是开放到十点,因为没有完全修好。我还高兴了一阵子:终于可以摆脱身上的污垢了。下了史纲课,我、范成和陈俊驰还兴冲冲地准备去跑步,刷十圈。刚到楼梯口,碰见黄晋国,我们得知了一个至关重要的消息:澡堂改为开放到八点。你妹!这是什么概念呢?史纲(第九、十节)下课时间是20:10。而我习惯晚上上完所有课之后再洗澡,所以下午就没去(下午某次出239Z的时候看到钟逸凡明显是洗完澡的样子,还想晚上就可以轻松一下了;晚上刷牙的时候再碰到他,我不由得说:“你看看你,真幸运啊!”)。总的结果是:没洗澡。

为了表示抗议(或者说为了不再弄脏床单),当天晚上我就睡在了椅子上。(来,让我解释一下这是怎么实现的。首先准备四张椅子,置于一条直线上,调整间距以适合躺下时身体的受力点位置,就可以躺下了。这一招我在军训的时候用过,不过那是中午;当然军训时我还有中午睡在一米长两边封闭的桌子上的经历。)这次,我放了一个枕头(上面有枕巾)。可惜没有被子,我只好找了这几天穿的一件衣服盖在上半身。这一夜过得非常艰苦(rough)。首先,椅子和床还是不一样,例如你可以将整条腿放在床上,感受着它均匀受力,而椅子不行,因为其中总有一段是空的,一点支撑都没有,所以身体实际上一直处于紧绷的状态。其次,椅子本来就窄,躺下之后手臂是不可能展开的了,晚上还要小心睡着的时候掉下去。还有,翻身很艰难,一是椅子窄,二是盖在身上的衣服要随着身体的翻动而移动,要不然就滑到地上了,所以每次翻身都是在清醒的情况下完成的。同时,我侧身睡的时候手臂必须得压在身下(在床上的话,侧向展开就好了),所以手指末端后来都冰凉冰凉的了(循环不畅),而且还酸麻。最重要的一点是,我忘了在群上的一条消息——星期二要下雪。当天晚上气温骤降,如果上有被子下有床垫那倒没事,但是我是在一个冰凉坚硬的椅子表面,罩着一件衣服睡的啊!所以每次夜里醒来(翻身或者被冻醒)的时候,我都能感受到那刺骨的冷气,感受到我的身体正在失温。不知道各位有没有这样的体验。我想,流浪汉也不过如此吧。

这么折腾了一晚上,我睡踏实了才怪。第二天,大物几乎睡了两节课,最后课堂测验的时候总算清醒过来了,还把一道简单的题做错了,还是极端弱智的错误。总之星期二上午就没好过。中午我发誓,澡堂一天不开放,我就一天不回到床上。当天的QQ签名,如果谁看见的话,是这样的:“这三天来,在沙河校区,你可以洗苹果,可以洗梨子,可以洗葡萄,可以洗西红柿——就是不能洗枣。”

下午下了语文课,路过路边两个大坑的时候我还责怪修管道的工人效率为何这么低。回到宿舍大堂,向右一看——“今天浴室开放时间:16:30-23:00,2013.3.19”。我将信将疑,问楼管大妈今天会不会还发生昨天的情况,得到的答案是不会。“修好了?”“是的,现在修好了,早点去洗吧。”

我还是有些担心,所以一回到宿舍,尽管九、十节还有选修课,我就立马准备东西去洗“枣”了。四天,整整四天!一卡通放入卡槽,打开水龙头,在这氤氲之中,我享受到了肉体的最高快感。这平凡的肉身,如何才能消受得起这美妙的感受。但是!别忘了,这是纯粹的感官愉悦,应当从精神层面对此进行进一步的挖掘。在那一刹那,所有的不净之物都离我远去,只余下我一个人徜徉在洁净之中,感受着心灵的洗涤。

一切都沉寂之后,我感到浑身轻松,就像玉石上的积灰被洗涤之后的那种清莹。顺带着,晚上也特别精神。没错,就这么短短几天,就一个“枣”就可以给我这么大的愉悦——毕竟,这种事情还是不常发生的嘛。

过了,也觉得那是一次难得的经历吧,毕竟之前知道肯定有些地方的孩子们条件艰苦,但是总觉得这种事情不会发生在自己身上。这次,就是一下马威啊!

分享到 评论

驱动笔记之二:一个成功的驱动程序与应用程序通信的实例(命名管道方式)

经过多次测试,一个笨拙的驱动程序和应用程序通信的实例终于完成了!我不会用 minifilter,所以就用了 named pipe 来解决。

代码如下:

// --- MessageThread.h

#include "wdm.h"

void MessageWorkerEntry(IN PVOID);
// --- MessageThread.cpp

#include "MessageThread.h"
#include "KernelPipe.h"

extern KEVENT keMsg;

void MessageWorkerEntry(IN PVOID pvContext)
{
    HANDLE hPipe = NULL;
    NTSTATUS ns = STATUS_UNSUCCESSFUL;
    PWCHAR pwszPipeName = L"\\??\\pipe\\HelloPipe";
    UNICODE_STRING uniPipeName={0};
    OBJECT_ATTRIBUTES ObjAttr={0};
    IO_STATUS_BLOCK IoStatus={0};

    KdPrint(("In MessageWorkerEntry."));

    RtlInitUnicodeString(&uniPipeName,pwszPipeName);
    InitializeObjectAttributes(&ObjAttr,&uniPipeName,OBJ_CASE_INSENSITIVE|OBJ_KERNEL_HANDLE,NULL,NULL);
    KdPrint(("Pipe name: %wZ", uniPipeName));

    ns = ZwCreateFile(
         &hPipe,            // File handle
         FILE_WRITE_DATA | SYNCHRONIZE,     // Desired access
         &ObjAttr,         // Attributes
         &IoStatus,                  // IO Status Block
         NULL,                   // Allocation size
         0,                      // File attributes
         FILE_SHARE_READ | FILE_SHARE_WRITE, //File share
         FILE_OPEN,              // Create disposition (must exist)
         //FILE_NON_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT,// Create options
         FILE_SYNCHRONOUS_IO_NONALERT,
         NULL,                   // EA buffer
         0 );                    // EA size

    KdPrint(("Open status: 0x%x", ns));
    KdPrint(("Pipe handle: %p", hPipe));

    if (NT_SUCCESS(ns))
    {
        ns = ZwSetNamedPipeState(hPipe, FILE_PIPE_MESSAGE_TYPE | FILE_PIPE_MESSAGE_MODE);
        KdPrint(("ZwSetNamedPipeState status: 0x%x", ns));
    }

    IO_STATUS_BLOCK isb;
    LARGE_INTEGER li;
    ns = STATUS_UNSUCCESSFUL;

    li.HighPart = -1;
    li.LowPart = FILE_WRITE_TO_END_OF_FILE;

    int i = 0;
    char ch[] = "This is some sort of test message.";

    for ( i=0; i<10; i++ )
    {
        ns = ZwWriteFile(hPipe, NULL, NULL, NULL, &isb, ch, (ULONG)strlen(ch), NULL, NULL);
        KdPrint(("ZwWriteFile status: 0x%x", ns));
    }

    KeSetEvent(&keMsg, 0, 0);
    ZwClose(hPipe);
    PsTerminateSystemThread(STATUS_SUCCESS);
}
// --- KernelPipe.h

#include "wdm.h"
#include "basetsd.h"
#include "ntdef.h"
//#include "ntifs.h"

#define FILE_PIPE_MESSAGE_MODE          0x00000001
#define FILE_PIPE_MESSAGE_TYPE          0x00000001
#define FILE_PIPE_QUEUE_OPERATION       0x00000000

#define FSCTL_PIPE_ASSIGN_EVENT             CTL_CODE(FILE_DEVICE_NAMED_PIPE, 0, METHOD_BUFFERED, FILE_ANY_ACCESS)
#define FSCTL_PIPE_DISCONNECT               CTL_CODE(FILE_DEVICE_NAMED_PIPE, 1, METHOD_BUFFERED, FILE_ANY_ACCESS)
#define FSCTL_PIPE_LISTEN                   CTL_CODE(FILE_DEVICE_NAMED_PIPE, 2, METHOD_BUFFERED, FILE_ANY_ACCESS)
#define FSCTL_PIPE_PEEK                     CTL_CODE(FILE_DEVICE_NAMED_PIPE, 3, METHOD_BUFFERED, FILE_READ_DATA)
#define FSCTL_PIPE_QUERY_EVENT              CTL_CODE(FILE_DEVICE_NAMED_PIPE, 4, METHOD_BUFFERED, FILE_ANY_ACCESS)
#define FSCTL_PIPE_TRANSCEIVE               CTL_CODE(FILE_DEVICE_NAMED_PIPE, 5, METHOD_NEITHER,  FILE_READ_DATA | FILE_WRITE_DATA)
#define FSCTL_PIPE_WAIT                     CTL_CODE(FILE_DEVICE_NAMED_PIPE, 6, METHOD_BUFFERED, FILE_ANY_ACCESS)
#define FSCTL_PIPE_IMPERSONATE              CTL_CODE(FILE_DEVICE_NAMED_PIPE, 7, METHOD_BUFFERED, FILE_ANY_ACCESS)
#define FSCTL_PIPE_SET_CLIENT_PROCESS       CTL_CODE(FILE_DEVICE_NAMED_PIPE, 8, METHOD_BUFFERED, FILE_ANY_ACCESS)
#define FSCTL_PIPE_QUERY_CLIENT_PROCESS     CTL_CODE(FILE_DEVICE_NAMED_PIPE, 9, METHOD_BUFFERED, FILE_ANY_ACCESS)
#define FSCTL_PIPE_GET_PIPE_ATTRIBUTE       CTL_CODE(FILE_DEVICE_NAMED_PIPE, 10, METHOD_BUFFERED, FILE_ANY_ACCESS)
#define FSCTL_PIPE_SET_PIPE_ATTRIBUTE       CTL_CODE(FILE_DEVICE_NAMED_PIPE, 11, METHOD_BUFFERED, FILE_ANY_ACCESS)
#define FSCTL_PIPE_GET_CONNECTION_ATTRIBUTE CTL_CODE(FILE_DEVICE_NAMED_PIPE, 12, METHOD_BUFFERED, FILE_ANY_ACCESS)
#define FSCTL_PIPE_SET_CONNECTION_ATTRIBUTE CTL_CODE(FILE_DEVICE_NAMED_PIPE, 13, METHOD_BUFFERED, FILE_ANY_ACCESS)
#define FSCTL_PIPE_GET_HANDLE_ATTRIBUTE     CTL_CODE(FILE_DEVICE_NAMED_PIPE, 14, METHOD_BUFFERED, FILE_ANY_ACCESS)
#define FSCTL_PIPE_SET_HANDLE_ATTRIBUTE     CTL_CODE(FILE_DEVICE_NAMED_PIPE, 15, METHOD_BUFFERED, FILE_ANY_ACCESS)
#define FSCTL_PIPE_FLUSH                    CTL_CODE(FILE_DEVICE_NAMED_PIPE, 16, METHOD_BUFFERED, FILE_WRITE_DATA)

#pragma comment(lib,"ntifs.lib")

extern "C"
__drv_maxIRQL(PASSIVE_LEVEL)
NTSYSAPI
NTSTATUS
NTAPI
ZwFsControlFile(
    __in HANDLE FileHandle,
    __in_opt HANDLE Event,
    __in_opt PIO_APC_ROUTINE ApcRoutine,
    __in_opt PVOID ApcContext,
    __out PIO_STATUS_BLOCK IoStatusBlock,
    __in ULONG FsControlCode,
    __in_bcount_opt(InputBufferLength) PVOID InputBuffer,
    __in ULONG InputBufferLength,
    __out_bcount_opt(OutputBufferLength) PVOID OutputBuffer,
    __in ULONG OutputBufferLength
    );

/*
extern "C"
__kernel_entry NTSYSCALLAPI
NTSTATUS
NTAPI
NtWriteFile (
    __in HANDLE FileHandle,
    __in_opt HANDLE Event,
    __in_opt PIO_APC_ROUTINE ApcRoutine,
    __in_opt PVOID ApcContext,
    __out PIO_STATUS_BLOCK IoStatusBlock,
    __in_bcount(Length) PVOID Buffer,
    __in ULONG Length,
    __in_opt PLARGE_INTEGER ByteOffset,
    __in_opt PULONG Key
    );
*/

#pragma pack(push,1)

/*
typedef unsigned long ULONG, ULONG32;
typedef unsigned short USHORT;
typedef unsigned char UINT8;
*/

typedef struct _WAIT_PIPE_PARAM
{
    __int64 liTimeOutvalue;
    ULONG   ulPipeNameLen;
    USHORT  bUsTimeoutValue;
} WAIT_PIPE_PARAM,*PWAIT_PIPE_PARAM;

typedef struct _NAMED_PIPE_CREATE_PARAMETERS  
{
    ULONG32      NamedPipeType;
    ULONG32      ReadMode;
    ULONG32      CompletionMode;
    ULONG32      MaximumInstances;
    ULONG32      InboundQuota;
    ULONG32      OutboundQuota;
    LARGE_INTEGER DefaultTimeout;
    UINT8        TimeoutSpecified;
    UINT8        _PADDING0_[0x7];
} NAMED_PIPE_CREATE_PARAMETERS, *PNAMED_PIPE_CREATE_PARAMETERS;

#pragma pack(pop)

#define WAIT_FORVER (0x8000000000000000)
#define PIPE_ACCESS_DUPLEX (3)

NTSTATUS ZwCreateNamedPipeFile (
                OUT PHANDLE phPipeHandle,
                IN ULONG ulDesiredAccess,
                IN POBJECT_ATTRIBUTES pObjAttr,
                OUT PIO_STATUS_BLOCK pIoStatus,
                IN ULONG ulShareAccess,
                IN ULONG ulCreateDisposition,
                IN ULONG ulCreateOptions,
                IN BOOLEAN bIsMsgType,
                IN BOOLEAN bIsMsgMode,
                IN BOOLEAN bIsNonBlocking,
                IN ULONG ulMaximumInstances,
                IN ULONG ulInBufSize,
                IN ULONG ulOutBufSize,
                IN PLARGE_INTEGER pliDefaultTimeout OPTIONAL );

NTSTATUS __stdcall ZwCreateNamedPipe(PWCHAR pwszPipeName,
                     ULONG ulMaxInBufSize,
                     ULONG ulMaxOutBufSize,
                     ULONG ulMaxClientCount,
                     PLARGE_INTEGER liTimeOut,
                     PHANDLE phPipe);

NTSTATUS __stdcall ZwConnectNamedPipe(HANDLE hPipe);

NTSTATUS __stdcall ZwDisconnectNamedPipe(HANDLE hPipe);

NTSTATUS __stdcall ZwSetNamedPipeState(HANDLE hPipe,ULONG ulMode);

NTSTATUS __stdcall ZwWaitNamedPipe(PUNICODE_STRING puniPipeName,LARGE_INTEGER liTimeOut);
// --- KernelPipe.cpp

#include "KernelPipe.h"

NTSTATUS ZwCreateNamedPipeFile (
                OUT PHANDLE phPipeHandle,
                IN ULONG ulDesiredAccess,
                IN POBJECT_ATTRIBUTES pObjAttr,
                OUT PIO_STATUS_BLOCK pIoStatus,
                IN ULONG ulShareAccess,
                IN ULONG ulCreateDisposition,
                IN ULONG ulCreateOptions,
                IN BOOLEAN bIsMsgType,
                IN BOOLEAN bIsMsgMode,
                IN BOOLEAN bIsNonBlocking,
                IN ULONG ulMaximumInstances,
                IN ULONG ulInBufSize,
                IN ULONG ulOutBufSize,
                IN PLARGE_INTEGER pliDefaultTimeout OPTIONAL )   
{    
    NAMED_PIPE_CREATE_PARAMETERS NamedPipeParms={0};
    NTSTATUS NtStatus={0};

    __try
    {    
        if ( pliDefaultTimeout )
        {
                NamedPipeParms.TimeoutSpecified = TRUE;
                NamedPipeParms.DefaultTimeout.QuadPart = pliDefaultTimeout->QuadPart;
        }
        else
        {    
                NamedPipeParms.TimeoutSpecified = FALSE;
        }  

        NamedPipeParms.NamedPipeType = bIsMsgType;
        NamedPipeParms.ReadMode = bIsMsgMode;
        NamedPipeParms.CompletionMode = bIsNonBlocking;
        NamedPipeParms.MaximumInstances = ulMaximumInstances;
        NamedPipeParms.InboundQuota = ulInBufSize;
        NamedPipeParms.OutboundQuota = ulOutBufSize;

        NtStatus = IoCreateFile(
                phPipeHandle,
                ulDesiredAccess,
                pObjAttr,
                pIoStatus,
                NULL,
                0,
                ulShareAccess,
                ulCreateDisposition,
                ulCreateOptions,
                NULL,
                0,
                CreateFileTypeNamedPipe,
                &NamedPipeParms,
                0    
                );

        return NtStatus;
    }    
    __except (EXCEPTION_EXECUTE_HANDLER)    
    {
        KdPrint (("ZwCreateNamedPipeFile: Exception occured.\n"));
        return GetExceptionCode();    
    }
}    

NTSTATUS __stdcall ZwCreateNamedPipe(PWCHAR pwszPipeName,
                     ULONG ulMaxInBufSize,
                     ULONG ulMaxOutBufSize,
                     ULONG ulMaxClientCount,
                     PLARGE_INTEGER pliTimeOut,
                     PHANDLE phPipe)
{
    NTSTATUS NtStatus=STATUS_SUCCESS;
    HANDLE hPipe=NULL;
    UNICODE_STRING uniPipeName={0};
    //ANSI_STRING ansiPipeName = {0};
    OBJECT_ATTRIBUTES ObjAttr={0};
    IO_STATUS_BLOCK IoStatus={0};

    RtlInitUnicodeString(&uniPipeName,pwszPipeName);
    InitializeObjectAttributes(&ObjAttr,&uniPipeName,OBJ_CASE_INSENSITIVE,NULL,NULL);
    //RtlInitAnsiString(&ansiPipeName, pszPipeName);
    //InitializeObjectAttributes(&ObjAttr,(ULONG)&ansiPipeName,OBJ_CASE_INSENSITIVE,NULL,NULL);
    KdPrint(("Name in ZwCreateNamedPipe: %wZ", &uniPipeName));

    NtStatus=ZwCreateNamedPipeFile(&hPipe,
            FILE_ANY_ACCESS,
            &ObjAttr,
            &IoStatus,
            FILE_SHARE_READ | FILE_SHARE_WRITE,
            FILE_CREATE,
            PIPE_ACCESS_DUPLEX,
            FILE_PIPE_MESSAGE_TYPE,
            FILE_PIPE_MESSAGE_MODE,
            FILE_PIPE_QUEUE_OPERATION,//blocking mode
            ulMaxClientCount,
            ulMaxInBufSize,
            ulMaxOutBufSize,
            pliTimeOut);

    if (NT_SUCCESS(NtStatus))
    {
        *phPipe=hPipe;
    }
    else
    {
        *phPipe=NULL;
    }

    return NtStatus;
}

NTSTATUS __stdcall ZwConnectNamedPipe(HANDLE hPipe)
{
    NTSTATUS NtStatus=STATUS_SUCCESS;
    IO_STATUS_BLOCK IoStatus={0};

    NtStatus=ZwFsControlFile(hPipe,NULL,NULL,NULL,&IoStatus,FSCTL_PIPE_LISTEN,NULL,0,NULL,0);

    return NtStatus;
}

NTSTATUS __stdcall ZwDisconnectNamedPipe(HANDLE hPipe)
{
    NTSTATUS NtStatus=STATUS_SUCCESS;
    IO_STATUS_BLOCK IoStatus={0};

    NtStatus=ZwFsControlFile(hPipe,NULL,NULL,NULL,&IoStatus,FSCTL_PIPE_DISCONNECT,NULL,0,NULL,0);

    return NtStatus;
}

NTSTATUS __stdcall ZwSetNamedPipeState(HANDLE hPipe,ULONG ulMode)
{
    NTSTATUS NtStatus=STATUS_UNSUCCESSFUL;
    ULONG    aBuf[2]={0};
    IO_STATUS_BLOCK IoStatus={0};

    do
    {
        if ((0xFFFFFFFC & ulMode)==0)
        {
            break;
        }

        aBuf[0]=((ulMode>>1) & 1);
        aBuf[1]=(ulMode & 1);

        NtStatus=ZwSetInformationFile(hPipe, &IoStatus, aBuf, sizeof(aBuf), FilePipeInformation);
    } while (FALSE);

    return NtStatus;
}

NTSTATUS __stdcall ZwWaitNamedPipe(PUNICODE_STRING puniPipeName,LARGE_INTEGER liTimeOut)
{
    NTSTATUS NtStatus=STATUS_UNSUCCESSFUL;
    IO_STATUS_BLOCK IoStatus={0};
    HANDLE hParent=NULL;
    OBJECT_ATTRIBUTES Oa={0};
    WCHAR  aTmpBuf[512]={0};
    PWAIT_PIPE_PARAM pWaitPipeParam=(PWAIT_PIPE_PARAM)aTmpBuf;
    INT   iShortNameOffset=wcslen(L"\\\\.\\pipe\\")*sizeof(WCHAR);
    UNICODE_STRING uniPipeParentName={0};

    do
    {
        if (!puniPipeName || puniPipeName->Length<iShortNameOffset)
        {
            NtStatus=STATUS_OBJECT_NAME_NOT_FOUND;
            break;
        }

        RtlInitUnicodeString(&uniPipeParentName,L"\\DosDevices\\pipe\\");
        InitializeObjectAttributes(&Oa,&uniPipeParentName,OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,NULL,NULL);
        NtStatus=ZwOpenFile(&hParent,0x100080,&Oa,&IoStatus,FILE_SHARE_WRITE | FILE_SHARE_READ,32);

        if (!NT_SUCCESS(NtStatus))
        {
            break;
        }

        pWaitPipeParam->liTimeOutvalue=liTimeOut.QuadPart;
        pWaitPipeParam->bUsTimeoutValue=TRUE;
        *((USHORT*)(&pWaitPipeParam->ulPipeNameLen))=puniPipeName->Length-iShortNameOffset;
        RtlCopyMemory((PVOID)((ULONG_PTR)pWaitPipeParam+sizeof(WAIT_PIPE_PARAM)),&puniPipeName->Buffer[iShortNameOffset/sizeof(WCHAR)],pWaitPipeParam->ulPipeNameLen);
        NtStatus=ZwFsControlFile(hParent,NULL,NULL,NULL,&IoStatus,FSCTL_PIPE_WAIT,&pWaitPipeParam,14+pWaitPipeParam->ulPipeNameLen,NULL,0);
    } while (FALSE);

    if (hParent)
    {
        ZwClose(hParent);
    }

    return NtStatus;
}

就可以了。

要点:

  1. 打开命名管道的时候要在 ObjAttr 中使用 OBJ_KERNEL_HANDLE,使其附加在系统进程([System])里。
  2. ZwCreateFileZwWriteFile 必须处于同一个线程中。(我之前尝试用 PsCreateSystemThreadlpContext 来传递 hPipe,结果 ZwWriteFile 返回 STATUS_INVALID_HANDLE(此时的 hPipe 为2位~4位16进制码)。

服务器端代码如下(我保证只会有一个线程调用 ZwWriteFile,所以我没考虑同步的问题):

#include "SnoopyTester.h"

int main()
{
    HANDLE hPipe = NULL;
    BOOL fRead = FALSE;
    DWORD i = 0;
    DWORD dwBytesRead = 0;
    char buffer[100] = {0};

    hPipe = CreateNamedPipe("\\\\.\\pipe\\HelloPipe", PIPE_ACCESS_DUPLEX, PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_NOWAIT, 2, 100, 100, (DWORD)-1, NULL);

    if ((hPipe) && (hPipe != INVALID_HANDLE_VALUE))
    {
        for ( i = 0; i <= MAXDWORD; i++ )
        {
            fRead = ReadFile(hPipe, buffer, 100, &dwBytesRead, NULL);

            if (fRead || dwBytesRead)
            {
                printf("Message received: %s\n", buffer);
                memset(buffer, 0, 100);
            }
        }

        printf("Application ends.\n");
        getchar();

        return 0;
    }
    else
    {
        printf("Cannot create named pipe \\\\.\\pipe\\HelloPipe\n");
        getchar();

        return 0;
    }
}

其中 SnoopyTester.h 包含了 stdio.h 和 windows.h。

运行结果如下:

Sc

分享到 评论

驱动笔记之一:内核命名管道问题的解决

(老鸟们请不要笑话我……)

最近正在做一个驱动程序,需要用到内核与用户层通信。我是个驱动开发的新手,所以想回归最简单最传统的 Windows 编程模式,第一个反应就是:命名管道。所以不要问我为什么不用 minifilter 的通信机制,原因很简单——我不会。

内核管道的实现在这里:http://blog.csdn.net/skyseacsn/article/details/6962858

#pragma pack(push,1)
typedef struct _WAIT_PIPE_PARAM     
{     
    __int64 liTimeOutvalue;     
    ULONG   ulPipeNameLen;     
    USHORT  bUsTimeoutValue;     
} WAIT_PIPE_PARAM,*PWAIT_PIPE_PARAM;     

typedef struct _NAMED_PIPE_CREATE_PARAMETERS      
{     
    ULONG32          NamedPipeType;     
    ULONG32          ReadMode;     
    ULONG32          CompletionMode;     
    ULONG32          MaximumInstances;     
    ULONG32          InboundQuota;     
    ULONG32          OutboundQuota;     
    LARGE_INTEGER     DefaultTimeout;     
    UINT8            TimeoutSpecified;     
    UINT8            _PADDING0_[0x7];     
} NAMED_PIPE_CREATE_PARAMETERS, *PNAMED_PIPE_CREATE_PARAMETERS;

#pragma pack(pop)     

#define WAIT_FORVER (0x8000000000000000)
#define PIPE_ACCESS_DUPLEX (3)

NTSTATUS ZwCreateNamedPipeFile (     
            OUT PHANDLE phPipeHandle,     
            IN ULONG ulDesiredAccess,     
            IN POBJECT_ATTRIBUTES pObjAttr,     
            OUT PIO_STATUS_BLOCK pIoStatus,     
            IN ULONG ulShareAccess,     
            IN ULONG ulCreateDisposition,     
            IN ULONG ulCreateOptions,     
            IN BOOLEAN bIsMsgType,     
            IN BOOLEAN bIsMsgMode,     
            IN BOOLEAN bIsNonBlocking,     
            IN ULONG ulMaximumInstances,     
            IN ULONG ulInBufSize,     
            IN ULONG ulOutBufSize,     
            IN PLARGE_INTEGER pliDefaultTimeout OPTIONAL )       
{        
    NAMED_PIPE_CREATE_PARAMETERS NamedPipeParms={0};     
    NTSTATUS NtStatus={0};     

    __try   
    {        
        if ( pliDefaultTimeout )     
        {     
            NamedPipeParms.TimeoutSpecified = TRUE;     
            NamedPipeParms.DefaultTimeout.QuadPart = pliDefaultTimeout->QuadPart;     
        }     
        else
        {        
            NamedPipeParms.TimeoutSpecified = FALSE;     
        }   

        NamedPipeParms.NamedPipeType = bIsMsgType;     
        NamedPipeParms.ReadMode = bIsMsgMode;     
        NamedPipeParms.CompletionMode = bIsNonBlocking;     
        NamedPipeParms.MaximumInstances = ulMaximumInstances;     
        NamedPipeParms.InboundQuota = ulInBufSize;     
        NamedPipeParms.OutboundQuota = ulOutBufSize;     

        NtStatus = IoCreateFile(     
                phPipeHandle,     
                ulDesiredAccess,     
                pObjAttr,     
                pIoStatus,     
                NULL,     
                0,     
                ulShareAccess,     
                ulCreateDisposition,     
                ulCreateOptions,     
                NULL,     
                0,     
                CreateFileTypeNamedPipe,     
                &NamedPipeParms,     
                0        
                );     

        return NtStatus;
    }        
    __except (EXCEPTION_EXECUTE_HANDLER)        
    {     
        KdPrint (("ZwCreateNamedPipeFile: Exception occured.\n"));     
        return GetExceptionCode();        
    }     
}        

NTSTATUS __stdcall ZwCreateNamedPipe(PWCHAR pwszPipeName,     
                     ULONG ulMaxInBufSize,     
                     ULONG ulMaxOutBufSize,     
                     ULONG ulMaxClientCount,     
                     LARGE_INTEGER liTimeOut,     
                     PHANDLE phPipe)     
{     
    NTSTATUS NtStatus=STATUS_SUCCESS;     
    HANDLE hPipe=NULL;     
    UNICODE_STRING uniPipeName={0};     
    OBJECT_ATTRIBUTES ObjAttr={0};     
    IO_STATUS_BLOCK IoStatus={0};     

    RtlInitUnicodeString(&uniPipeName,pwszPipeName);     
    InitializeObjectAttributes(&ObjAttr,&uniPipeName,OBJ_CASE_INSENSITIVE,NULL,NULL);     

    NtStatus=ZwCreateNamedPipeFile(&hPipe,     
            FILE_ANY_ACCESS,     
            &ObjAttr,     
            &IoStatus,     
            FILE_SHARE_READ | FILE_SHARE_WRITE,     
            FILE_CREATE,     
            PIPE_ACCESS_DUPLEX,     
            FILE_PIPE_MESSAGE_TYPE,     
            FILE_PIPE_MESSAGE_MODE,     
            FILE_PIPE_QUEUE_OPERATION,//blocking mode     
            ulMaxClientCount,     
            ulMaxInBufSize,     
            ulMaxOutBufSize,     
            &liTimeOut);     

    if (NT_SUCCESS(NtStatus))     
    {     
        *phPipe=hPipe;     
    }
    else
    {     
        *phPipe=NULL;     
    }     

    return NtStatus;     
}     

NTSTATUS __stdcall ZwConnectNamedPipe(HANDLE hPipe)     
{     
    NTSTATUS NtStatus=STATUS_SUCCESS;     
    IO_STATUS_BLOCK IoStatus={0};     

    NtStatus=ZwFsControlFile(hPipe,NULL,NULL,NULL,&IoStatus,FSCTL_PIPE_LISTEN,NULL,0,NULL,0);     

    return NtStatus;     
}     

NTSTATUS __stdcall ZwDisconnectNamedPipe(HANDLE hPipe)     
{     
    NTSTATUS NtStatus=STATUS_SUCCESS;     
    IO_STATUS_BLOCK IoStatus={0};     

    NtStatus=ZwFsControlFile(hPipe,NULL,NULL,NULL,&IoStatus,FSCTL_PIPE_DISCONNECT,NULL,0,NULL,0);     

    return NtStatus;     
}     

NTSTATUS __stdcall ZwSetNamedPipeState(HANDLE hPipe,ULONG ulMode)     
{     
    NTSTATUS NtStatus=STATUS_UNSUCCESSFUL;     
    ULONG    aBuf[2]={0};     
    IO_STATUS_BLOCK IoStatus={0};     

    do
    {     
        if ((0xFFFFFFFC & ulMode)==0)     
        {     
            break;     
        }     

        aBuf[0]=((ulMode>>1) & 1);     
        aBuf[1]=(ulMode & 1);     

        NtStatus=ZwSetInformationFile(hPipe, &IoStatus, aBuf, sizeof(aBuf), FilePipeInformation);     
    } while (FALSE);     
    return NtStatus;     
}     

NTSTATUS __stdcall ZwWaitNamedPipe(PUNICODE_STRING puniPipeName,LARGE_INTEGER liTimeOut)     
{     
        NTSTATUS NtStatus=STATUS_UNSUCCESSFUL;     
        IO_STATUS_BLOCK IoStatus={0};     
        HANDLE hParent=NULL;     
        OBJECT_ATTRIBUTES Oa={0};     
        WCHAR  aTmpBuf[512]={0};     
        PWAIT_PIPE_PARAM pWaitPipeParam=(PWAIT_PIPE_PARAM)aTmpBuf;     
        INT   iShortNameOffset=wcslen(L"\\\\.\\pipe\\")*sizeof(WCHAR);     
        UNICODE_STRING uniPipeParentName={0};     

        do
        {     
            if (!puniPipeName || puniPipeName->Length<iShortNameOffset)     
            {     
                NtStatus=STATUS_OBJECT_NAME_NOT_FOUND;     
                break;     
            }     

            RtlInitUnicodeString(&uniPipeParentName,L"\\DosDevices\\pipe\\");     
            InitializeObjectAttributes(&Oa,&uniPipeParentName,OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,NULL,NULL);     
            NtStatus=ZwOpenFile(&hParent,0x100080,&Oa,&IoStatus,FILE_SHARE_WRITE | FILE_SHARE_READ,32);     

            if (!NT_SUCCESS(NtStatus))     
            {     
                break;     
            }     

            pWaitPipeParam->liTimeOutvalue=liTimeOut.QuadPart;     
            pWaitPipeParam->bUsTimeoutValue=TRUE;     
            *((USHORT*)(&pWaitPipeParam->ulPipeNameLen))=puniPipeName->Length-iShortNameOffset;     
            RtlCopyMemory((PVOID)((ULONG_PTR)pWaitPipeParam+sizeof(WAIT_PIPE_PARAM)),&puniPipeName->Buffer[iShortNameOffset/sizeof(WCHAR)],pWaitPipeParam->ulPipeNameLen);     
            NtStatus=ZwFsControlFile(hParent,NULL,NULL,NULL,&IoStatus,FSCTL_PIPE_WAIT,&pWaitPipeParam,14+pWaitPipeParam->ulPipeNameLen,NULL,0);     
        } while (FALSE);     

        if (hParent)     
        {     
            ZwClose(hParent);     
        }     

        return NtStatus;     
}

(吐槽一下百度空间的“插入代码”功能,总是出现神排版!)

引入了管道之后,我尝试创建管道,但是一直返回 0xc0000033(STATUS_OBJECT_NAME_INVALID)。我纳闷了,为什么呢?我查看了 KdPrint("zW"),使用的名称“\.\pipe\hellopipe”确实被正确地转成了 Unicode 字符串啊!那么为什么系统总是说我的名称错了?

我查遍了所有的资料,里面写的都是,本地命名管道(服务端只能采用这种格式)采用“\.\pipe\pipename”的格式,远程管道可以采用“\servername\pipe\pipename”的格式。那么为什么我的名称是不对的?
后来我偶然找到了一个页面(http://us.generation-nt.com/answer/create-named-pipe-kernel-driver-help-27790252.html),里面讲述了原因。翻译如下:

Thus whereas in user-mode format of pipe is , in kernel it is “\??\pipe\pipename”. In addition, in kernel default security context is LocalSystem which is not allowed to access network.

所以尽管用户态的管道名称格式为“\server\pipe\pipename”,在内核中其为“\??\pipe\pipename”。而且,在内核中,默认安全上下文是 LocalSystem,该安全上下文不允许访问网络。

好了,知道原因,修改代码,调试,成功~

分享到 评论

Astraea's Caroline 2.1.0.5 已经发布

Astraea’s Caroline 通用游戏启动器 2.1.0.5 版本发布。这很可能是最终的版本,以后不再更新。

地址:http://pan.baidu.com/share/link?shareid=151557&uk=3121145127

(该版本需要手动下载安装,不再提供自动更新功能)

更新至:

  • Astraea’s Caroline 2.1.0.5
  • AcUpdate 1.1.0.13
  • AcAppIDUpdate 1.1.0.5
  • AcAppIDBrowse 1.0.0.4
  • 修正 Windows XP 下有时会启用 DWM 设置的问题
  • 修正“最近游戏”列表不会添加新项目的问题
  • 修正一些界面 bug
  • 稳定性增强
  • AppID 更新增加对 Windows 7 任务栏的支持
  • 添加对 Windows 游戏的搜索支持(需要 Windows Vista 及以上)
  • 添加选择性搜索功能
  • 添加自定义配色方案功能

截图:

Sc1

未使用主题时的外观

Sc2

启用桌面合成之后的仿 Windows 8 Style 外观

Sc3

修正后的菜单和工具栏

Sc4

美化后的设置窗口

Sc4

可选择多种配色方案

Sc5

关于

分享到 评论

Serenity, impressive.

People don’t like to be meddle with. We tell them what to do, what to think. Don’t run, don’t walk. We’re in their homes and in their heads and we haven’t the right.

I am a leaf on the wind. Watch how I soar.

分享到 评论

Astraea's Caroline 还在继续更新

Screenshot 1

“关于”界面

Screenshot 2

在桌面组合开启时的样子

Screenshot 3

使用传统风格系统主题的样子


当前版本为 2.0.5.1。

分享到 评论

2012届高中毕业生自招亲历——自主招生是怎么救了我的命的

大家对自主招生不陌生吧。有的广告甚至宣称,自主招生考试、保送生考试和高考是进入高校的三大途径,我要狠狠地嘲笑这一点;而且不仅是我,有智慧的老师们都这么做。不过,自主招生确实救了我的命。接下来我会详细解析自招流程与其带来的好处。

先说第一点。自主招生的重要性很多时候被过分夸大了。可以说,保送生考试和高考是进入高校的“唯二”途径(走后门不算)。为什么?没错,有电视主播说其子自招跑到北大面试,北大看过之后当场拍板要了——但是大哥,这可是十亿分之一的概率。你每年见过几个人在自主招生阶段就被马上要走了?没有多少对吧,要不然各路媒体又要进行宣传轰炸了。所以,自主招生再怎么样都只是高考的助推器,如果你没料,自招再好而高考一塌糊涂也照样会落榜,因为自招只是降分录取,而不是加分(除非你过了高校在该省的录取线)!

再说第二点。这里我要给大家介绍自招的流程了。

前言:带自主招生的高考录取制度和普通的高考的录取制度是不一样的,如果你不清楚这一点,请看完下面的东西之后再把最后一段好好看完。这样你才清楚自招的威力。


Step 0

请先看好各个学校的自主招生制度!一般来说,在开始报名的时候各大高校网站上都会贴出来。请详细阅读,不要放过一个字,有疑问马上打电话问清楚。例如,这个降分是降大类的分还是系的分、允许报什么专业、平行志愿与非平行志愿的省份制度区别,等等。

Step 1

挑选联盟,或者一些散兵游勇(如中大在广东的独立考试、复旦千分考。此部分个人决定,在此省略)。三大联盟:华约、北约和卓越,请大家根据自己的情况选择。三者之间的一些规则(如,选报学校的限制、笔试科目)不一样,请一定要看清楚。另外,有些年,例如2011-2012学年度,华约和北约是死掐在一天笔试的,所以也做好只能选其中一家的准备。卓越一般是不冲突的。我选择了北约,没有选择卓越(因为不想连续两个周末被占用……)。

[PS. 港大和其他学校不一样,会多一个剑桥联合招生计划(考试全英。面向未来的港大学生),以及入学计划(面向高考有志于选择港大的学生)。]

Step 2

最好在在准高三的暑假就开始准备自招,当然如果学得比较好可以晚一点开始。例如我是奥林匹克班(简单说就是搞竞赛的班)的,也有一些超前学习的东西了(化学),所以在奥赛培训结束之后(9月份中)才开始准备。买书不大有必要(除了物理和化学),因为即使是我一位同学每天刷题都没刷完。

Step 3

准备完成(其实很难,一般就只能看一部分)之后,到了来年1月份到一个统一地点笔试。一般来说每个省都会设点,所以不用很紧张。(问题是,考点附近物价会飞涨,所以请各位家长提前做好准备。)试题网上都有。考试的科目如下:

北约——

a.语文语文不算难,不过要有一定的阅读积累,答题的时候也要有自己的心得;不过不要太注重这个,因为这毕竟是试题,是有标准答案的,所以还要委屈一下各位讨厌高考语文的人啦。

b.数学数学也不难,除了小题之外就是高考压轴题的轰炸啦~我们这一届可是对这个考试颇有微词的,因为之前只需要考7题(文科选前4道题,理科选后4道题)而这次题量加大到如此程度。不过说是压轴题,还是跟高考的难度设置有所类似的。要点是拿下小题和前面的大题,后面的如果有时间再慢慢做。(高考也是这样!我和一些同学的血泪总结……)

c.英语这个……看个人造化了。我英语很好所以不用担心这个。我觉得这个难度和高考的没什么区别,都是可以刷题的。(我最后检查完剩下的时间用来睡觉了。)

d.物理&化学(两个科目同时考)这个嘛……我推荐没有化学联赛经历的人主攻物理,有化学联赛经历的人也主攻物理。(画外音:“废话!”)为什么?这两者考的都是竞赛内容,而二者之中物理显得更为容易一点。(如果有人没搞过化学竞赛,看自招的化学书不头大的,可以否认这一点。)而且我们这一届的物理考题,后两道大题根本就是从书上摘下来的!如果你看书了,背题了,绝对满分!(我考完回去之后捶胸顿足……)其他的,就要看各位的物理思维了。化学方面,考得太简单了(对于我们进行化学竞赛的人来说)!基本上就是相当于省初赛的一个子集。在这里告诉没有玩过化学竞赛的人,需要背记的东西很多,有时间还不如把你的高考生物提高了。

最终结果是,虽然其他三科不咋地(个人感觉),但是凭借着英语和化学的高分,我顺利杀入下一轮。

华约——

考的是语英+数+文理(美其名曰人文科学+实验科学)。这个考试我没经历过,所以不好写。

Step 4

面试是大型考试的必备环节。考完之后两个星期你就会收到面试的offer,同时可以看到你的成绩啦。然后就面试吧。我去的是港大和北航(北大的资料没用心准备,胡乱塞一通,结果材料评审就没过)。各大高校的面试地点不一样的,一般在其本部。(我很幸运,在北大进行港大的面试,在北航进行北航的面试,车程不远。如果我报四川大学我就惨了……)所以请大家规划好自己的行程。面试的话……就看自己的技巧了。如果说纯技巧也不对,你要有料,就是有自己的观点(同时不能和主旋律唱反调)。我记得在北航的时候我提出了“自然人”与“社会人”的观点(虽然不全是原创的),相信是这个给我加分了(我很担心能不能过,因为我不小心在要回收的问卷上写了答题草稿……)。总之,理科生要有文科积累,文科生要有理科思维,这样的人是高校最喜欢的。

Step 5

如果你过关斩将赢得了所有战役的胜利,那么在4月份你就可以收到确认函了。主要内容是:你通过了我们的自主招生考试,现在给你优惠多少多少,要参加高考才有效,而且请注意我们的学校在你的志愿的位置,确认吗?一般来说这种信函要留3份:给高校、留在中学、自己备份。而且这张信函所有的陈述都要看清楚!如果你填错了,那么优惠就无效了。可以缓一缓,因为很多学校都要求填上高考分数,然后在放榜之后多少天之内寄回,所以时间不用赶的。

Step 6 高考并填志愿去吧。接下来对平行志愿和非平行志愿的省份进行讲解。

a.平行志愿省份你们的选择很多,风险小,但是优惠幅度小。无论如何,也要看清楚确认函的内容,并且严格按照指示执行。关于志愿排位这一点我之后还会讲到。

b.非平行志愿省份你们也不用着急,虽然“一考定乾坤”的压力比平行志愿省份的压力要大很多,但是你们获得优惠幅度也会更大。所以请考虑清楚了,志愿填在什么位置。

Step 7

最后,如果你发现(或者估计,如广东)你可以上线,就大胆报吧。最后的最后,就是一张录取通知书了。


最有趣的地方就在这里了。

有心的人从前面可以看出,我是广东的考生——没错,2012届,获得北航20分降分录取优惠的,全省只有3个,其中就有我。

然后,我的高考其实并不理想,628(这也不是秘密了),甚至比华工的好专业的分还要低。

但是我最终上了北航的机械工程系啊!这里是怎么来的?这就是自主招生的功劳了。

(但是,各位高考的学子们,不要过于依赖自招,要努力学习啊,因为要以高考为本,不要像我一样考砸了!上大学之后一样要继续努力的!)

广东今年实行的新政救了我的命。

去年,批次分布如下:

一本-二本A-二本B-……

今年,批次分布如下:

自主招生-一本-二本A-二本B-……

看到没有?多出来了一个“自主招生”批次,所有的自招院校会优先看这个批次的学生。


先讲一下普通的高考录取制度。(这是广东的制度,外省未必适用!)

广东实行平行志愿。所以,所有档案按照分数排好(具体排位请参见排位系统,这里有很详细的说明),一个一个入档。这就像信号灯对象(Semaphore,Windows 多线程编程里会用到的)一样,每个时候在机器里只有一份档案。

伪代码描述如下——

For Each s As Student In Examiners
    If s.AcceptableUniversities(1 To s.AcceptableUniversities.Count – 1).Full Then Continue For
    For Each u As University In s.AcceptableUniversities
        If s.TotalScores >= u.AdmissionScore Then
            s.SendTo(u)
            s.Enrolled = True
        End If
    Next
    If Not s.Enrolled Then Continue For
Next

然后让我们来假设数据。例如,今年有一本线上清华大学、北京大学和X大学在广东招生,人数分别为100、100和1000,广东考生一共1500人。

OK,机器开始读档。先取第1名的档案,看到她A组(A志愿组)第一志愿是清华大学。清华大学人满了吗?没有。那就送过去。于是现在三所大学分别剩余99、100、1000个名额。

第2名,以此类推,直到第100个都是选清华的,然后看第101个。结果他的A组第一志愿也是清华,对不起,人满了,看A组第二志愿。第二志愿北大,进了。第102个,A组第一志愿、第二志愿第三志愿都是清华,抱歉,他只能等到A组第一志愿不是空的人都投档完毕了他才能进入B组进行投档。也就是说,如果B组里他选了北大,他的分数也足够,但是由于北大在A组已经招满了,他还是进不去。(当然,如果涉及到专业,那就把三所大学设定成三个系就行了。简单说,就是递归。)

就是这样。旧的不去,新的不来,如此往复,而且严格遵照顺序。


然后再看自主招生批次的录取制度。

自主招生批次的考虑顺序是在其他所有批次之前的。那么,这时候怎么出成绩呢?毕竟正式的投档还没开始呢。这里就要涉及到一个预投档线的问题了。

预投档线在自主招生的录取时是很重要的参考依据,每个学校都有所不同。那么它是怎么计算出来的呢?

伪代码描述如下——

Dim intEnrolledStudentCount As Integer = 0
For Each s As Student In Examiners
    If intEnrolledStudentCount > CurrentUniversity.MaximumEnrollStudentCount Then Exit For
    If s.AcceptableUniversities.Contains(A) Then colPrecastScores.Add(s.TotalScores)
Next
Return colPrecastScores.MinimumValue

从第1名开始,如果该学生的第一志愿是该学校,则将这个学生的总分录入一个表中,直到这个表中的学生总数达到计划数的105%(不是100%,这就解释了为什么所有学校都说每年自主招生的录取人数不超过计划数的5%),然后取其中最低的分数作为预投档线。自然,有时预投档线可能偏高或者偏低,只要学校觉得不合适,就可以向教育部门申请调整录取情况(如,生源太好了,想多招收一些,就增加招生人数)以获得一份新的表,继续操作得到一个新的预投档线——第二预投档线。第二预投档线就是最终的结果,该学校一切自主招生的录取以它为准。这些操作都是不公开的,但是结果会被公布出来。之后,所有的优惠都是以它为准,如第二预投档线是660,甲获得降20分录取的优惠,那么考到640以上可以进去了(当然,这是不确定的)。今年北航在广东招收55个人(理科),按100%投档线计算录取线是649,而第二预投档线是是647,所以我压线进去了。这不得不说是含有侥幸成分——但是到了大学,不大可能再有侥幸,拼搏吧少年!

分享到 评论

Sat Jul 28 2012 00:00:00 GMT+0800 (中国标准时间)

最后一节课了。其实前一天我专门找到遇见科组调课,想把1班和2班的课表调换(原:遇见C1.4/C2.3 实验C1.3/C2.4,调换之后:遇见C1.3/C2.4 实验C1.4/C2.3)想取得最大的眼泪收效,结果到了上课那一天那些家伙居然没有更改课表!(事后证明,原课表的安排也不错。)

其中,3班在昨天上了最后一个课时的课,林文琪准备的是《回忆积木小屋》。不过据反映孩子们都没看懂,所以之后我们使用这个是有很大的风险的。


[C1]

1班的学生们说,最后一天上的是他们最喜欢的三节课(十天、实验、遇见)。其实在我们来之前,十天的家伙们已经成功把他们搞哭了。(后来我们把他们的眼泪榨干了 :-),导致遇见的效果没有预期好~)

我对这节课的准备在两天前就开始了(如果算上选曲子,那要从公开课前一天开始)。我从曲库中选出各种离别时可以放的曲子,再根据1班的特点选出最好的一首——Nothing I’ve Ever Known,作为催泪弹。

那天另外两位倒是没我准备那么充分(因为前一天我一开始拒绝透露今天我要说的内容,而最终要透露要他们准备配合的时候又因为种种原因而没人有空听)。陈晓菲做了一个幻灯片,打励志牌;黎荣舜则什么都没有(而且如果我没带无线上网卡那他真的要干讲了)。然后大家各自讲了一下各自的思路,准备开始。

原本我预计是要用 Butterfly 的不同风格(对应《数码暴龙》的开场曲和第54集的离别曲)来引入。不过班主任没有意识到课已经开始了,也就没有去维持纪律,导致引入不成功,两首歌被浪费了。

一开始是黎荣舜,他趁着我带了无线上网卡的机会下载了《倔强》的 MV,然后一上来就是不痛不痒的寄语,结束之后放视频。自然——孩子们没有什么反应。

然后是陈晓菲。她准备的是 Jessica Cox 的事迹,以及《没有翅膀的鸟》。(顺带提一下,《苍蝇的一分钟生命》也很不错。)她延续了之前我们课堂的风格,就是提问竞猜来调动气氛,让大家猜 Jessica 能做什么——当然,孩子们惊叹于 Jessica 的精神。但是我总觉得,孩子们对主旨,就是要有坚强的意志,感受不充分。而《没有翅膀的鸟》则没有得到共鸣,孩子们毕竟还是太年轻,也没有体会过生命的残缺会带来什么。最后陈晓菲一段动情的演讲——主要是讲要再逆境中拼搏——收效也不算好。

我在开场之前受到《没有翅膀的鸟》的启发,想到高考前心理辅导的老师给我们放过一个叫《蜗牛》的 Flash 短片(插话:推荐!推荐!“我一步一步向上爬,等待着太阳来照着我的脸……”),坐在我身边的一位同学(男的)因为觉得他就像那只蜗牛,当时就哭了。我开场也没说什么,就打开了这个视频,简要地概括了一下蜗牛遇到的东西(怕他们看不出),并且说了我的同学哭过的历史。他们静静地看着(对比:鸟那个,由于画风过于卡通,而且音乐也不够好,所以小孩都问“他为什么这么做”,或者是在笑),唱到第二段旋律的时候已经开始有人(蚊子)在跟着唱。当视频结束之后,孩子们看到蜗牛最终爬上了树顶,发出了惊叹声。已经有几个感情把控不住的人(1男1女)开始落泪了。接下来是重头戏,精心编辑好的幻灯片,配合 Nothing I’ve Ever Known。唱歌的过程就不细说了,有视频,而且……我唱歌很渣。唱完之后不止两个人开始哭了。(我呢?嗯,虽然说处处的眼泪已经成为一种收藏,但是为了配合情景我还是得来一点~)

至此,效果已经达到了。(据孩子们的反映,他们觉得这一段歌曲是他们印象最深刻的。“梧桐树放了一首歌,我看到歌词与现在的情景很像,我禁不住哭了。”)

然后陈晓菲准备宣布下课。班主任真的不会当啊,听到“下课”就要下课,她们估计是等下课等不及了吧?好不容易把孩子们稳住,进行最后一个环节——这个环节我之前没有设计,到了快下课为了补偿那首绝顶好听的抒情版 Butterfly,我决定顶住压力放这首歌。放的时候让他们闭上眼睛用心听,我也跟着闭眼了。一首歌曲放完,又有人哭了。有些孩子直到歌曲放完之后20秒还没睁开眼睛,他们已经沉浸在这氛围之中了。我觉得这是最成功的。


[C2]

但是对于2班这个没有1班和我们那么熟,而且更为活泼的班级来说,就要换一种策略了。催泪弹不好使,得用欢快的结局。不过他们俩估计没意识到这一点。

黎荣舜上台,还想打悲情牌,于是在我放 Butterfly 的时候他让学生回忆这10天大家做了什么。不过还好——这次没放《倔强》了,看来他有学习能力。

陈晓菲则没变,还是 Jessica+鸟。(这次,孩子们有笑的了。)

没办法,一定要改。我一上台就问:“大家想要来抒情点的,就像刚才那样,还是来欢快点的?”答案不用说了吧。然后就是一堆火柴人动画,把之前在1班而没在2班放过(因为投影仪效果没1班好,而且之前没找到音频线)的动画都在2班放了一遍。在欢笑中(严重超时了),课堂结束了。


后记:这天中午我们可是叫了外卖哦~我们和2班的孩子们一起吃的~

分享到 评论

上课日志(2012-07-22~2012-07-26)

这些天的课都是正式的课,最后一节课我会单列出来。


7月22日我们上的是单极马达,关于这个玩意儿,有兴趣的人可以上网找一找,其实就是电池+导线+磁铁,然后一个左手定则就解决问题了。

其实这天也没什么好讲的了。一班和二班都有点乱,其中一班更糟糕一些。

讲解原理方面,当然不能给这些小孩讲左手定则,也不能过度地讲电生磁,而且很糟糕的是他们不会知道奥斯特的。那么……我就发掘已有器材,亲手试了奥斯特实验。别说,效果真的不错:一节五号电池,一根导线(例如,电视机的信号线,不过要求是绝缘层不能太厚)和一个指南针,就可以了。(普及一下,对于还没学过这个实验的朋友,导线平行于小磁针且在其斜上方不远处时效果最好。原因的话,课本里有。)看起来1班和2班的孩子们觉得这个演示实验很新奇嘛~当然,讲解为什么小磁针会偏转时还是花了很多功夫……因为还不能涉及“场”的概念。

4班(不是我们三人小组教的)觉得这节课很无聊,原理就更不想听了。就是啊,这节课是我们上的所有课里面最难上的(因为只要弯一下铜丝就可以了,还有现成的模板,纸塔什么的还至少有小组之间的创意比拼),因为气氛很难调动——这一点和后面(第8课时)的绳子挂物的纪律难以维持形成了很大的对比。

(插播:应该是这天中午吧。我们吃午饭后,回启明时,就在校门前的斜坡上,我被一个小萝莉缠住了。这家伙好像是5班、4班还是1班的,有点忘了,不过更可能是前两个。我们一群人当时正在有说有笑地走着,突然这小萝莉就从路边逼近到路中间,拦住我的路。为什么她不拦着别人呢?我不知道。然后发生了如下对话。“呃,我要过去。”“不行。”“为什么不行?”“你要帮我买一瓶汽水。”嗯,我认人的技术很糟糕,所以认不出这家伙是谁,所以也没法做出决定。“为什么要买汽水?”“不要汽水也可以,零食。”我跟你很熟吗?虽然可能熟,但是我还是不认识你啊……所以我只好绕路,但是我向右,她也向右,我向左她也向左,挡了我几次。最后估计她也有点不好意思了,还是让我走掉了。我的脸很可能又像熟透的大番茄了!某些组员调侃说:“哇,她看上你了哟!”“你居然连一个小妹妹也不放过!”“她长得还不错哦~”啊啊啊,谁叫我不善于和女生打交道……我又不像某些人那样是大情圣,怎么样都能哄人,而是一遇到意外的事情就会脸红,并且从来只会理睬(我喜欢的&&道德和法律允许的)人。)

不过,启明的男女生之间倒是隔阂很严重。如,女生拒绝与男生合作,如果有一个三人小组中有一女二男(或者一男二女),则这“一个”就会在一边干看着,没有外力就不参与。


7月23日,大坑爹。

本来呢,今天我们是不用上课的。按照原来的课表,我们23、24两天都不用上课的(23日上午“浩洋学社活动”,下午游园活动;24日我们实验科组没课)。后来,上午的活动取消了(由于对方效率低下),改为上公开课!接下来你就会看到我们是怎么在23日从没课到接到课的。

一开始,原定有3个科组上课:世界银行、经济(忘了具体内容)、生活中的选择。后来,上生活中的选择的科组的一个关键人物生病了来不了,于是课程安排的家伙们要物色一个代替他们的科组。我们作为启明最受欢迎的科组,首先接到了任务(这时是科组长接的),然后我们小组都知道了这件事。考虑到我们真的很需要休息(21日我们没课,但是去听了其他科组的课),科组长花了很大的劲儿才推辞掉这个“美差”。听科组长说,当时安排课程的家伙“头上的汗就下来了”(当然,如果有一个科组缺课,这个压力对其他科组来说是很大的)。然而,我们组的其他人(其实不包括我,我还在收电脑)“兴奋地冲下楼来,告诉安排课程的家伙说我们有十足的把握上好明天那节公开课”。然后,笑容就出现在了对方的脸上~其他人高兴,她也高兴啊……他们还不知道发生了什么……

然后就是备课!我们因为这一乌龙,只剩下一个晚上的时间去备课了。艰苦的斗争。要上一节高质量的课,只有一个晚上的准备时间……(开始还预定一组化学实验的,后来下午我们还要开会,开完会我再跑到一德路那边的时候已经晚上八点多了,化学用品店都关门了。所以即使我强烈建议要玩火,就是七氧化二锰和乙醇的实验,各种化学实验最终还是没能进行。)我们就首次地采用了YY(语音软件)。

插入:我们原定进行鸡蛋实验(一连串用鸡蛋完成的实验),所以我才会跑去买化学试剂,因为主要目标是硫酸铜(当然还有自己要的七氧化二锰和乙醇啦)。后来由于种种原因,如怕孩子觉得浪费、会导致脏乱等等,我们取消了鸡蛋实验,而换成了后面说的实验组。

那晚的讨论非常热烈,之后在YY上再也没有这么热烈的群讨论了。

总之,备着备着,到最后我们确定了几个方案:用辊子运输石块(桌子+人)、纸桥(把后面的课调到前面了!)、表面张力+大气压强,以及纸飞机。其中后两个是备用方案,撑场用的。商议出这几个方案之后我们就暂停讨论了(一点多了),我直接下线了,所以不知道他们后来说了什么。

第二天也是很坑爹的!原本约定的是7:40到(8:40开始上课),结果我7:30到(还是为了赶时间,打的赶去的),在3楼(秘密基地)和4-5楼(教室)转悠了很久,还和2班的几个家伙打了一盘斗地主~但是直到8:40,到快要上课的时候都没见到一个人影。可知道,在这期间我可是电话轰炸了(谁叫你不接电话!)罗泽仑和陈晓菲,总计37(33+4)次,但是只有最后一次陈晓菲才接了电话,并且给出来了一个非常坑爹的信息:这群家伙在2楼为公开课排练!到我下去的时候他们已经接近排练完了,我一点忙都帮不上……

他们排练的主题是法老和神要建一座金字塔,由此引发了一串问题。啊啊啊,我没任务,所以自觉地去录像去了。(现在看来这是很正确的。很有幸,录像记录到了一切。)在录像中你可以看到那天的各种坑爹表演:在教室里,在操场上。还有最后的坑爹时间,做实验不足而自由活动有余,所以拿来放视频(建桥的视频)了……

到了公开课结束的时候,法老(文台,郑浩鸣)和神(罗泽仑)特别受孩子们的欢迎。(孩子们觊觎的应该是他们俩的两柄权杖吧?解释一下,权杖是PVC管,就是第一个实验的实验器材之一,以及网球、一次性塑料杯和绳子粘成的,看起来蛮不错的。)几个孩子都想要这权杖,权杖几经易手,最终被两个5班的女生拿了,而她们最喜欢的事情是拿着权杖,用网球或杯子对着人的胸口大喊:“神命令你死去!嗞嗞嗞……”大佬和文台都很配合,做倒下状。而我则拒绝倒下(哼,我才不吃你这一套),所以直到第二天她们都会追着我问“为什么你还不死”……

中午出现餐具。林文琪同志(会骑自行车)与陈嘉怡同志(不会骑自行车)两位因为公开课上完了且非常成功而非常高兴,在校门口借了1班一位学生的自行车,然后林骑车,陈坐在后座上,从大斜坡上滑下去。(唉,当时我傻了,没有先分析该行为的危险性而做出风险评估。估计也是被公开课冲昏了脑子,也跟着大笑着跑了下去追车玩。)林文琪是下惯了这种坡,喜欢不减速而直接冲到坡底。到了离坡顶三分之一的地方,陈嘉怡对当前的速度感到恐惧,想让林文琪停车。(但是林文琪正在兴奋地尖叫诶,哪里注意过后座上的人怎么想。)然后,她选择了直接跳车。砰!陈嘉怡就摔倒地上了。当时擦破了左手的第一关节,左手臂和额头,感觉颅骨受到重击。(嗯,透露一下,她哭了。如果陈嘉怡同志想删掉这个描述可以跟我说。)然后……就是鲁迅先生说的,围观。学生、附近杂货店的小孩和一些大人都来围观。(纯粹看热闹的人应该被清除。)好不容易把他们赶走之后有几个好心的人来了:一个学生和一个大人拿来了创可贴,还有双氧水。当然,这种小伤,在这样的路面上跌倒,最好不要用创可贴,因为用了反而容易感染破伤风(学过高中生物的都应该能理解);双氧水的话,会很疼,我们担心陈嘉怡受不了(哭上加哭……),也没用。过了几分钟,一个学生(6班,钟礼剑)留了下来。他说他知道附近的医院(我们要解决的主要是脑震荡的可能性,所以最好去医院),我们就跟他走了。

在前往医院(同和医院)的途中,钟礼剑和我聊了一路。主要内容是他以前曾经多次摔过手,其中4次骨折;而同和医院原来是一个治骨头的医生开的小诊所,后来他越来越有名,诊所也越来越大,后来发展成同和医院。这个医生成为师傅之后培养了一堆徒弟,而这些徒弟们则是目前医院骨科的中坚,不过他本人隔一天会来一次医院。废话不多说。到了医院,主要就是一系列医疗操作啦。等了一段时间之后,诊断,处理,开药,打针(包括试针)。(于是后来几天陈嘉怡都以伤口涂着一篇红药水的样貌出现。)钟礼剑一直陪着我们

下午游园会,我本来是第8组的(在2班),但是我们组因为经历了公开课和中午的事情,都很累了,所以没有参与游园的组织。不过我们还是去玩了一下。我本人玩了说颜色的游戏,光凭破纪录的得分就有12分了,不过我没打算计算积分。(不过最后的最后,我的记录在雄踞了30分钟之后被一个胖胖的女生以一个之差打破了……)


7月24日

因为台风来到广州,所以两个营区都停课了。到了晚上天气好的时候,我去购书中心买了点书。


7月25日

第一节是6班的课,忘了具体的情况。

下课之后还去串课……然后好像是第三节,我破坏课堂秩序,估计把新课堂小组的家伙气死了……

这两节课,我因为没有对这节课的讲课预期,而且连续主讲了几天比较累,所以把讲课的任务交给另外两位了。

下午我们做的是绳子挂物的实验。(解释一下,就是把各种小东西挂在一根绳子上,挂上会有相应的加分,而用工具则会按扣分。)然后……黎荣舜同志编造了一个令人无语的情景,什么八路军要运物资抵达,反正一较真就不堪一击的那种。关于这个实验,我们老师做的最好成绩是扣70分挂起所有物资,用了一张A4纸和2个回形针。

下午是1班的课,气氛很活跃。不过由于快到结营了,所以纪律比较乱。1班的课没有什么好讲的。

虽然2班是在26日上的课,但是我还是要把它移到这里讲。

26日上午第一节,因为3班和4班同时上课,我们得去帮忙。这两个班的孩子们都很有创造力,有两个组做出了只扣60分就完成的方案,一个回形针和一张A4纸。(我们老师原本还要讲解最佳挂物的方式并且展示我们的方案的,结果现在都不敢了。)这些都有录像。

到了2班,我又把自己当做学生,他们俩讲解完规则之后,我直接和一组学生在那里玩了。他们试验了一些方案之后还是没有完成,而此时别的小组都已经挂完了所有物资(最好成绩也是扣60分)。原来他们的设计是把绳子挂物作为一个小组竞赛来进行的。既然赢不了,我就和他们一起挑战理论极限——扣30分解决问题。我们不断尝试(多亏有一个小孩指出了正确方案来说服同伴,因为我不好直接点明)。到了下课,课间都结束了,我们组还在继续——这又把新课堂的家伙们气死了,因为这一节是语文课,我们搞得小孩子过度兴奋……不过我们还是保留了进度。

第四节上课一开始我们继续尝试,用了大约5分钟,我们成功了!只扣30分!三根橡皮筋解决!当然3班和4班的人不服,因为他们的物资是有3个网球的(因为各个班级的时间问题,我们安排的物资数量是不尽相同的),而我们只有两个。但是由于设计上我们只能容纳两个网球的位置,无法加入第三个网球,所以之后加码的尝试失败了。

出现的神级方案:一根橡皮筋挂两个网球(3班),以及一个回形针夹着一张包着所有东西的A4纸(3班、4班)。有照片。


7月26日

倒数第二节课。由于之前一天我们对这节课的安排产生了分歧,故不同小组上课的内容不一样。5班、6班按照原定的计划上纸飞机的制作与原理讲解,3班、4班按照小孩子的要求(虽然最后他们讨厌这节课)上了厕所中的科学(囧!主要是马桶的连通器原理和电灯泡的拱形原理),我们则把公开课没用上的表面张力讲了一下。(呼~前一天我可是做了充足的准备的,包括翻译了一段 National Geography 的视频……)

先上的是2班,这堂课很正常。1班则在一开始谁也没有放成功(包括我们老师),导致了小小的混乱。其他的还好。


(附记:刚才是2012-08-04 19:00,女子赛艇项目最后一桨真的是决定胜负的关键!我拍着手大叫“银牌,不要拿铜牌”……最终中国的家伙们还是很争气~希腊的家伙们估计要气死了。)


附:小组安排

[启明]

吴桐、陈晓菲、黎荣舜 - C1/C2

陈文豪、林文琪、赖其祺 - C3/C4

罗泽仑、陈嘉怡(、郑浩鸣) - C5/C6

[春华]

吴鸣、林静、何绮祺 - C1/C2

分享到 评论

记昨天晚上回家路上发生的有趣事情

昨天看完电影(秘密,拒绝透露)回家,走到楼下的喜士多想买点东西。进门发现一下一个结账的是一个老外(这家伙买了一堆馒头和士力架)。

收款员:(显示器上显示金额为23.5元)

然后,这老外掏出一张10元和四张1元。高潮来了。此时他手中还有一张50元、一张10元和一张5元,只见他把5元递了过去!

收款员估计被雷到了……

这时我正试着直接用手去帮他指明该拿哪一张钱。

幸好收款员会说一点英语(我SB了,为什么我不直接说出来而要指……),直接用英语说:“Ten Yuan.”老外:“Ten Yuan? Oh, ten Yuan.”然后他把10元递了过去。

此时我正站在他的右后方(他斜对着收款机),估计也很尴尬,想看看周围有没有人发现这么囧的事情。他看到我盯着他和收款机,低头(他比我高)挤出一丝微笑(他应该知道我知道刚才发生了什么了,所以会觉得有点苦逼……)。作为回礼,我也得微笑……感觉有点像兔斯基的“无所谓”的 feel(没错,兔斯基一般情况下没有除了眼睛之外的五官,不过动作总是会给人一种 feel 的嘛)~

然后这老外被找了五毛,右手提着馒头左手攥着(没错!大手!)士力架出门了……

现在我能体会某些老外数学是怎么学的了!

分享到 评论

华师附中2012届高三(1)班众人小传 [18/57]

高三一班的同学们。

2016-05-25 附注:原地址在 http://hi.baidu.com/micstudio/item/d45f65e9dfa45f2b5a7cfb41

查看更多

分享到 评论

第三天和第四天(2012-07-20+2012-07-21)

第三天,我们教的是纸塔。

上午第一节课,我恰好没课,就跑到三班去看林文琪上纸塔的课。纸塔的幻灯片是林文琪做的,所以她非常熟悉里面的内容。看她眉飞色舞,从土塔讲到小蛮腰,整整讲了35分钟,而且那些小孩兴趣颇高。其中,她还穿插了各种细节和数据——当然,这整节课都是她设计的,她肯定熟悉,所以讲起来得心应手。

第3节课,到了我们。

第二节的时候,陈晓菲(她已经先跑去打印了讲稿)和黎荣舜还在看讲稿,准备怎么讲呢。我由于看了林文琪的课,已经清楚她的幻灯片里有什么(并且有点不道德的是,由于第一节她借了我的电脑放幻灯片,我就在没有说的情况下“截留”了幻灯片~)、大概要怎么讲,讲得好和不好的地方分别是什么,该怎么调整。这时我心中已经有数了,想着这两位狂看讲稿效果会怎么样,我差点笑了。我决定变一下课堂的形式,要把这幻灯片的效果发挥到极致——林文琪是先展示塔的材质再打出图片,我则要先展示图片再让孩子们猜是什么材质,然后开蛊(广州话,揭开谜底)。又比如,她讲课的时候提到了《碟中谍4》中有关哈利法塔的片段,但是没有图片——那些小孩子都没看过《碟中谍4》,你跟他们这么描述有什么用?于是我又动手找了相关的图片,插入到相应的位置上。总之,在听课到我讲课之间我是做足了准备工作。

然后我对黎荣舜说我来主讲(嗯,不是我损,如果他们讲,不知道那些学生受不受得了这么枯燥的念稿课),黎荣舜就把讲稿给我。我看也没看就扔到一边,说:“我不需要这东西,一切我来搞定。”关电脑,去上课。

二班的效果明显比一班好,见视频。

——插话,我发现一件悲惨的事情:我讲得最好的那节课由于相机问题,只录了8分钟!最精彩的地方被错过了!

——再插话,我觉得上课之类的,教案是死的,讲稿是死的,但是人是活的。看讲稿还不如去听听别人怎么讲,然后自己消化反思,再研发出更好的教学方式,“提升学生们的听课体验”(模仿微软的说话风格啊~)。另一点,示范是很重要的,不管是对初中生,还是对我们这些准大人,这一点下面还会讲到。

准备在一班讲的时候,黎荣舜说让陈晓菲主讲吧,我说我再来一堂。开始还好,讲着讲着就有点累了,状态没有上午好。好不容易撑过了小蛮腰(上午是轻松完成),在开始动手的时候我实在不想动了,找了一个小组就坐在椅子上,看他们做纸塔。没有空调,只有风扇,浑身大汗。

第四天,我们组没课。大佬叫我们10:30到,我原来还准备为去上大学买衣服(我能用的一共就3套衣服)呢。去吧去吧。

然后就有了很好玩的事。

上午第三节,听了一堂“遇见未知的自己”科组的课,讲心理减压的。我个人觉得,这堂课出彩的地方不多,比较失败的地方一个是没有很好地启发学生去观察思考(这堂课的主要目标是要他们知道最不好的事换个角度看也会发现好的方面,教师举出一些换角度图片做例子,还要求学生分享让自己最不舒服的事),另一个是写的东西太多,还有过于关注少数人而忽略了“沉默的大多数”。这堂课也有录像。

到了中午,吃饭,然后我不想陪着一些老师呆在有空调的餐馆里和一些小孩玩“杀人”游戏,于是跑回了没有空调的办公室……呃呃呃。我原本打算玩电脑的,结果另一个老师(小草新课堂,赵翼)来找我们的科组长。后来才知道,之前一次试讲的时候,她从新课堂的科组长那里听到说我们科组长的数学很强,而且之前他支教的时候就讲数学,所以她想来找他问上课的问题。

Prelude: 前天(按照这篇日志发布的时间算,是大前天)放学的时候我站在楼梯口,看到一个孩子眉心中间有一道痕迹(不是疤痕,而是像一条浅浅的线),于是进办公室说那个孩子可能有阴阳眼。(关于看这些,我只能算入门。另请尊重每个人的习惯。)然后林文琪就问:“哎呀,是不是那种能看到什么什么的阴阳眼啊?”好嘛,这话让进来的赵翼听到了,然后她就表现出了过量(适量?足量?)的兴趣。然后我就被揪着和她说了十几分钟的牛鬼蛇神,一直到我们(实验站一帮人)要进地铁站了才结束……天啊我要崩溃了。

赵翼看见我,然后又开始准备说牛鬼蛇神了。Blah blah blah,又是十几分钟,我快支撑不住了。(你不知道她躺在躺椅上闭眼问话那样子有多惬意!我还紧张得要死,上次已经领略过发问机的厉害了,我只能苦苦撑着,累得要死。)这时黎荣舜出现了!他一进门就说:“你们是不是又在讨论什么阴阳眼啊?”赵翼:“是啊。”黎荣舜:“WT学识非常渊博的,唯一的知识漏洞是在韩剧和日剧那里。”(点评:这个不全对。我学识渊博么……我觉得不啦,知道我知道的是很正常的,不知道才不正常。然后,我亚洲电影看得很少,世界所有国家的电视剧都看得很少,所以知识漏洞比大家认为的要大得多啊~)赵一听来兴趣了,要我帮她解决等会上课的问题——莫比乌斯环+七桥问题。我勒个去!这个要是将深层原理讲清楚了初三的都不懂,你拿这个给准初二的讲课?!不过我还是提出了一些能让这堂课更容易被孩子们接受的建议,并优化了一些课程的内容。

正式上课的时候,我先再说一次“不是我损”:赵同学上课真的很糟糕啊……不过鉴于她之前对上课讲的知识没有深刻了解,而且她的组员没有帮她准备这节课,因此大家请原谅她下面的表现。现总结如下:

  1. 规则还没讲清楚就开始游戏,小孩子输了肯定不服;
  2. 解释(莫比乌斯环+七桥问题)的时候导入还好,再往后就糟糕了:“我们把一个平面扭曲180°”、“这你们在大学才会学到,这还是什么关于宇宙的”,解释七桥问题的时候真的逻辑一团糟,我都没法听懂她究竟想表达什么,难怪孩子们被问到“听懂了吗”的时候各个眼睛呆滞;-
  3. 不注意课堂氛围,她居然没看到她讲七桥问题的时候下面有人玩手机,有人填听课表(就是学生评价老师上课好坏的表),听她讲的只有大约50%,而她没注意到冷场的情况,还是继续半兴奋地讲了下去。另外她说“A岛”、“B岛”等等的时候用粉笔在相应位置画圈,但是不回头看学生;
  4. 示范少,例如讲莫比乌斯环的时候她说“从中间剪开”,是直接在黑板上画图,而不是拿着一个莫比乌斯环演示;另外从三分之一处剪断这个她也没有示范,学生们有60%都没听懂。

其他的,看视频吧……我现在也累了。

总之,上课是要吸取别人的经验来丰富自己的经验的,所以我并不看低上课比我糟糕的人,也不羡慕上课比我好的人,人人相互学习嘛,又不是敌人。

分享到 评论

无题

最近我去了一个初中,参加一个夏令营活动,算是轻量级支教吧。三天以来很忙,没有时间去学习大学的一些内容。

我的软肋是,从初中开始我的数学一直都不算好(虽然高中时我们班是全广州最强的班)。你也知道,有一个这么严重的短板,虽然在高中通过其他科目拉分还能撑一下,但是大学时以数学为基础,甚至数学本身将会是个麻烦事。

我昨晚正在陶醉于我的授课技巧越来越成熟,突然在空间中看到有个同学说“在高中没有好好发展数学是我最严重的错误”(实际上她的数学能力很强),而且说这话的原因是“积不定积分时碰到了没见过的三角恒等式”!顿时就如被泼了一盆冷水,一点心情都没有了。

我总觉得和这些人相比我似乎缺了些什么。我开导自己说这些人没体验给小孩上课的快乐,但是理性的我立刻指出这意味着我的数学水平不断落后。好像这次夏令营就是垃圾,但是我又不觉得。非常痛苦。我缺了什么……

追求一切完美是 CC 的通病吗……

分享到 评论

关于第一次和女生打伞一起走

7月18日,下了第三节课,我们实验组全体出来吃午饭。走着走着,居然下大雨!我们没有预料到这一点,6个人,3把伞。当然,伞我是没带的;当然,我一向是不怕雨淋的(小时候就很喜欢在大雨里面跑)~不过考虑到下午要正装出现在学生们(二班)面前,以及带着的计算机和相机都是怕水的,我尽量在突出层遮着的地方走。然后……每个人都呆在伞里了,除了我~

现在的情况是,除了陈晓菲,其他人都是处于 in pairs 的状态。于是大佬(罗泽仑)说:“陈晓菲你去遮一下吴桐吧。”开始我说其实我在没有雨的地方走着就可以了,但是到了房子的边缘,我实在撑不下去了,只好进了伞里。

你知道么?一个女生在大雨里给你打着伞(当然,CC 基本上是外貌协会的成员,因此对于某些女生,让她们帮你打伞你还不如雨中漫步呢!),你手里提着一个笔记本电脑,背着相机,这是什么一种小清新(乱用了……)的场景啊!哎呀居然有女生给你打伞,而不是你被强迫要求照顾女士哦!而且距离过近的话时不时会发生表皮接触~嗯,反正我之前是没有体验过这个的,因此会有种种美好的感觉,请大家不要笑抽了。

默默地走到了一家沙县小吃店里。一路上(其实也就三十来米),由于在同一把伞下,我能感受到她的存在诶,甚至是呼吸~就是存在一个人,活着的,正常的,而且就在我身边,是一个女生。呀呀呀,这个可是很美好啊!(这是 CC 的通病么……)

吃中午饭。这时雨停了!我勒个去……

归程。

刚刚迈出沙县小吃店的店门,居然啊居然,又下暴雨了……然后我被要求打伞了 = =

右手拎着电脑+一个手提袋,斜挎着相机,只有左手是空的了,你妹!于是左手打伞。总之我是很照顾她的了,伞柄在她的左肩位置(我站在左边)。录像的时候我举着手,手臂能定住,所以现在其实也不算很难。然后陈晓菲觉得我这个动作有点别扭(演杂技呢你?),于是问:“你为什么不用右手打伞啊?”这这这……如果用右手打伞,那么左手要护着电脑,当然要放在伞下,右手又要到达左肩的位置……其实做一个模型就知道,我的身体会过于靠右(至少在旁观者眼中应该是)。我当然不能答出这些,只是回答:“因为我怕电脑淋湿了啊!电脑怕水的。”天,感觉像在博弈……

然后:“那这样,我帮你提电脑包,你右手打伞吧。”还能如何?给她呗。然后电脑包连同手提袋她一起拿了。当然,由于她也挎着一个包,所以不知道提着这么多东西她的难受程度是多少。

再然后,她把电脑包抱着!抱着啊!问我:“我这样拿行不行?”嗯,她也许知道计算机(是的,还是用正式的名称吧)对于我的重要性吧,基本上我都数字化了。但是抱着,像抱着一个婴儿那样抱着,天啊!你难道不觉得,自己带着的很贵重(应该用“重要”一词更好)的东西,被一个女生小心翼翼地保护着,是一件很……嗯,怎么说……的事情吗?也许可以填入“令人激动”这个词吧。

再然后,我就用右手打伞了,只挎着一个相机,而她带着一堆东西。我不知道在旁人眼中这是什么样的一种情景,不过根据模板分析,这似乎意味着什么……

最后到了教学楼下,其间还是说了一些话的。

唉,第一次被女生打伞,第一次帮女生打伞,这经历就这样经历了。对于我未来的女朋友来说,我可能少了这两个第一次……


嗯,今天(2012-07-19)还有一个家伙对阴阳眼以及相关的东西非常感兴趣的……

分享到 评论

第二天上课(2012-07-19)

还好,今天没有出什么意外。就如我的 QQ 签名——二班孩子爱拆台,一班孩子很欢乐~

不过其实一班和二班最大的区别……还是男女生待遇(相互之间)的问题。

第二节课是二班的课。昨天我们的自我介绍惨遭冷场,因此至少我,对二班有点不太好的印象。今天我们的实验是针扎气球+斜立易拉罐,附带任务是发种子。

出乎我意料的,二班的小家伙们很喜欢扎气球的实验。最后“黎叔”把这个实验搞到了接近20分钟!

然后是我的易拉罐实验~我觉得引入还可以,主要就是很好地勾起了他们的好胜心与好奇心。然后大家很欢乐地玩了15分钟(有一组只用了25秒就立起了2个易拉罐,这是我们没想到的。前一节课我们在三班看到的牛人则是约30秒3个,而且还有人能推测出水平面的位置,在最短斜边的高以下)。到了最后,我让他们做两个易拉罐立起来的实验(当然,从理论上分析,这是不可能完成的),他们就做了……当然试了一段时间没有人成功。就是因为多了这段时间,我们严重超时了~呵呵。后面的种子,反正就是陈晓菲讲清楚了。

有小孩子说是因为上面的拉环没有取掉,没办法,只能未置可否。他们问:“老师,你们实验过没有?”我:“我们实验过,不过没有成功。”(很坑爹对吧!)但是到底为什么,二班没人问。

另外,二班那个比较沉默寡言的女生,在易拉罐实验完成之后把桌子上的水用纸巾擦干了,而其他的同学都没有注意到这个细节。因此,这个人以后如果碰上机遇,应该会是不一样的人。

到了中午,我在回到办公室的时候提出了新的讲解易拉罐实验原理的方法(早上坐地铁时想到的)。嗯,只剩下一班没有上过课了,绝佳的实验品。之前其他组的解释是把易拉罐看成一个圆柱体,与桌面有一个接触点,然后用类似杠杆原理的方式,“重心与接触点在一条垂直线上就不容易倒”来解释。我考虑到这样既不科学,小孩子也听不懂(特别是三班!),因此我突出了易拉罐斜立时的两个支撑点(请注意观察!),把它们类比为人的两只脚,然后叫一个小孩(实际上叫了凹凸曼,这个人见后文)上来,分开两只脚站着,把他向左向右偏,说明易拉罐与人向左向右偏的情况很像,不过只要感觉重量在两只脚之间(两个支撑点之间)就可以稳了。这种说明方法,小孩子更容易听懂,而且这才是有科学性的解释。

一班的开场白非常顺利~之前我们听说一班会很闷,但是介绍过之后觉得他们其实很活泼的。嗯,很晚了,所以还是写的简略一些,上课实录请见录像。

下课的时候,一班的家伙会来找我们实验组的老师(这一点和二班的不一样),问问题。当我用坑二班的手法坑完一班之后,发完种子下课了,就有学生来问我为什么两个易拉罐就不行了。对了,一班有几个人知道重心和平衡!有一个外号“凹凸曼”、一个外号叫“蚊子”、一个不知外号但是眼睛很大的男孩,这三个人特别活跃。问原因就是前两个人问的。凹凸曼知道重心这个概念,所以三下两下就解决了;另一个嘛……只好跟他说我们“通过理论计算得出‘不可能’这个结论”,然后说:“实验也是要有理论依据的嘛(实际上这不是很符合真实的情况,如姜-泰勒效应的发现),你以后就会学到怎么样用理论来预测实验的可行性。”(天,这是什么逻辑!)

啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊!第二天啊!

分享到 评论

昨天在地铁站发生的事情,以及某2B行为

昨天(对,是昨天),我上完课(http://hi.baidu.com/micstudio/item/514983412a6da712886d10fd)后乘坐地铁回家。
到了林和西,旁边有两个人(实际上是三个,一个没有参与讨论)说怎么怎么走。我从他们的话里听出他们要去一个能转五号线的站。

附地图:

Map

已知:我正在乘坐的是三号线,林和西→体育西路方向。三号线有一个很奇怪的地方,和广州其他所有线路都不一样:体育西路这个站,有3个方向。对于一些没有坐过三号线的人来说,广州地铁上三号线的示意图是非常恼人的。

简单地说,三号线分两段。一段就是我正在的那一段(机场南-体育西路),第二段是其余部分(天河客运站-番禺广场)。其中,第二段是一条线,和其他的线路(比如一号线、五号线等等)很像,从一个总站坐到另一个总站,理论上可以在车厢里睡大觉。

但是问题来了,从机场南坐到天河客运站,必须在体育西路站下车,睡觉的话……准备接受超过2小时处罚吧。因为林和西所在的这一段是相对独立的,只有一趟列车往返地从机场南到体育西路。(换句话说,今天上午我赶车,碰到“还有2分钟入站”的事情已经算我幸运了。)

其实,广州地铁总公司啊,你们为什么不新开一条线路(或者把这段三号线命为另外的编号),而一定要把三号线搞成这样一个怪模样呢?想不通。

又已知,广州地铁的每个中转站都有一个类似“循环利用”的标志,表明这是哪两条线路的中转站。

接着说。两个人中,A 认为要到体育西路转一号线,然后通过某种方式转到五号线(嗯,算是读懂了图吧);B 认为直接从林和西坐到珠江新城转五号线就行了。在 B 的意见即将要变成现实之时,我说话了~我纠正了 B 的方法的错误,当然是用一种耐心解说的方式……呃,寥寥数语肯定是无法讲清楚这种一开始会让人头晕的图的。

总之,我解决了说理问题。解决完之后,B 说:“麻烦你了。”最后我还为三位指明了正确的下车方向(体育西路站,我所在的支线上是有两个下车方向,分别对应两条主线的行车方向)。嗯,我觉得这是对我最大的赞扬!鼓掌~(啪啪啪)好了,我不是好大喜功,我只是想通过自己的、每个人的力量,让广州使人觉得更亲切,让更多来广州的人觉得,在广州还是有好人存在的。

好有成就感哦~


顺便揭露两个关于广州交通的2B事情。

  1. 亚运即将来临时,市政府宣布即将对公交系统实行免费乘坐制度~呜呼!这下子,人们都跑去坐公共交通工具了,确实减轻了交通负担,而且减轻了环境负担。但是公交系统受不了了,主要是亏本,其次是拥挤问题,因为客流量太大了。结果,免费政策实行没几天就被一个发放50元出行补贴的公告代替了,从此再无下文。
  2. 当 BRT 系统刚开放时,新颖的站台让许多广州人觉得不适:前后门看起来是一样的啊!为了某种原因(形成广州交通新秩序?),出现了某公告,声明:“公交车前门进后门出的规则,在今天,作废了!”然后就是一片混乱。到了 BRT 系统成熟的时候这些拍脑瓜的家伙大概是觉得拥挤的站台有损广州形象,于是拍屁股:“建议大家还是遵守前门进后门出的习惯”……看看!真没把话说绝!我勒个去……由于再也没有严格的习惯或者规则约定,现在的 BRT 车站之混乱实属全广州公交系统之最。你不信的话可以来看看,一般时候,从后门进公交车的人比从前门进的多得多!但是,从前门下车和从后门下车的人数差不多,因此我们这些严格遵守传统习惯的人下车(从后门)有75%以上的几率遇到强大机械力(某同学语)。换句话说,后门的人类交换效率非常非常低。这不是典型的2B行为是什么!
分享到 评论

上课记录(2012-07-18)

今天是我们第一次正式讲课。

今天我们小组(实验组)有四节课,分别是上午第二节(6班,罗泽仑组)、上午第三节(3班,陈文豪组)、下午第一节(6班,罗泽仑组)和下午第二节(2班,陈晓菲组)。

第一节课没什么问题,罗泽仑真的是有很强的人格魅力~总之那些孩纸们(呃,13-15岁的人类)都比较听课,气氛很活跃(欢乐~)。第二节虽然陈文豪他们开始控场有点失败(过于学术,学生不想听),后半段很好。下午第一节我有点累,所以没有很认真听。具体的内容我都已经录制成视频放到115上了。

但是到我们这里问题来了。(个人意见。)

一开始我们 Ice Breaking 的时候,我们原来的想法是搞一个“同花顺”(扯!绝对扯!)的外壳,附上搞笑版三人引入与个人引入。结果实施时出现了混乱,陈晓菲在我们说完三人引入的台词之后忘了还有每个人的引入,就直接宣布做实验了……我在这边放着幻灯片,莫明其妙地听着要开始做实验,本来想纠正的,不过已经开始分组了,所以再回到介绍环节是不理智的……开场就乱了,出师不利。

之后进行实验。我们本来打算一开始是书分不开的实验(陈晓菲)到可乐-曼妥思实验(我)到牛奶-水彩颜料-洗洁精实验(黎荣舜),结果由于早上上了课,而且这些小东西互相通风报信导致他们已经知道上课内容,所以我感觉我们被当作猴儿耍……

具体内容见视频。

没有被记录到的细节:

1、我画了两个图,就是为了让那些小东西能看懂,结果那些家伙居然对图一点反应都没有(我讲解的时候)!

2、坐在中间(“验”组)的一个小男孩,在开始上课的时候是没有表现出想听的意向的(目光……),从玩颜料(第3个实验)开始就有点活跃了。到了陈晓菲做总结的时候,我盯着他,发现他正在似笑非笑地看着我(估计我当时在微笑。我总是不自觉地微笑,而且似乎这样的微笑很容易吸引观众)。我当时就笑出来了,他也笑了。

3、这个班男女隔阂非常严重!听说4班是极致(势不两立),但是我觉得2班也够可以了。我们在2班的分组是4(2+2)+3(2+1)+3(1+2),就是2男+2女+2男+1女+1男+2女(“实”、“验”、“站”),女生、男生分别抱团,单一的男女生就被孤立了。

4、“验”组的一个女生(坐在从教师视角中间偏右的位置),看起来非常非常内向,总是低着头,表情……嗯,跟LMY(我的一个高中同学)刚入学的时候差不多。她明显是被孤立的。在书本实验要进入讲评阶段时,我下去强制收回小孩子们还在玩的书本(高中奥数小丛书!)。收到她的的时候,她刚刚一页一页把书页叠好(这样就拉不开了,是我们的实验内容),我说:“呃,该收书了。”接下来她的动作我有点忘了,反正我觉得这样下去要等到何年何月,感到有点不耐烦,认为她是拒绝交还。这小子违反纪律啊嘿!正准备强制收回时,旁边坐着的班主任(也是志愿者,和学生们年龄相仿)问:“你是不是想把书复原还给老师?”她点了点头,没说话,但是脸上有种坚定的神情。不知怎么,我对刚才我的想法感到惭愧,并一直默默等到她完成这任务。幸好我没有强制收回,要不然可能又要伤了这同学的心。天!班主任的这句话真的太及时了!

5、下课之后,4提到的那位同学来问我们三个老师(正在收拾实验器材)关于可乐-曼妥思实验的科学依据。我在课堂上讲的似乎很模糊……好吧我要看看视频。“为什么把盐放进可乐里可乐也会爆出来?”(场外观众,真的是这样吗?我们没试过……)诶,我负责这个实验,所以我很耐心地讲解了~反正就是催化的问题嘛。最后这位也听懂了。呼~算是一个成功吧。

分享到 评论

Astraea's Caroline 通用游戏启动器已经正式发布!

详情请见:http://tieba.baidu.com/p/1722228137

Screenshot 1

Screenshot 2

2.0.0.0 版安装:http://115.com/file/ankzs1cs

升级失败修复补丁:http://115.com/file/any4xvo5#AcUpdateBugFix.exe

分享到 评论